Contents
from bokeh.resources import INLINE
import bokeh.io
from bokeh import *
bokeh.io.output_notebook(INLINE)
Loading BokehJS ...

Introducción a la visualización de datos con Python

  • La visualización de datos es el arte y la ciencia de contar historias cautivadoras con datos.

  • ¿Por qué Python?

  • Python realiza cálculos numéricos y científicos avanzados con librerías como: numpy y scipy, alberga una amplia gama de métodos de de métodos de aprendizaje automático gracias a la disponibilidad del paquete scikit-learn

  • Proporciona una gran interfaz para manipulación de big data gracias a la disponibilidad del paquete pandas y su compatibilidad con Apache Spark

  • Genera gráficos y figuras estéticamente con librerías como seaborn, plotly, etc.

Manejo de datos con pandas DataFrame

  • La biblioteca pandas es un conjunto de herramientas de código abierto extremadamente ingenioso para manejar manipular y analizar datos estructurados. Las tablas de datos se pueden almacenar en el objeto DataFrame disponible en pandas, y los datos en múltiples formatos (por ejemplo, .csv, .tsv, .xlsx y .json) pueden leerse directamente en un DataFrame.

Ejercicio 1: Lectura de datos desde archivos

  • En este ejercicio, leeremos de un conjunto de datos. En este ejemplo se utiliza el conjunto de datos diamantes

  • Abre un cuaderno jupyter y carga la librería pandas

import pandas as pd
import warnings
warnings.filterwarnings('ignore')
  • Especifique la URL del conjunto de datos:

diamonds_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/diamonds.csv"
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Use the usecols parameter if only specific columns need to be read.

diamonds_df_specific_cols = pd.read_csv(diamonds_url, usecols=['carat','cut','color','clarity'])
diamonds_df_specific_cols.head()
carat cut color clarity
0 0.23 Ideal E SI2
1 0.21 Premium E SI1
2 0.23 Good E VS1
3 0.29 Premium I VS2
4 0.31 Good J SI2

Ejercicio 2: Observación y descripción de datos

  • En este ejercicio, veremos cómo observar y describir datos en un DataFrame. Volveremos a utilizar el conjunto de datos de diamantes

  • Cargue la librería pandas:

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
  • Observe los datos utilizando la función head:

diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75

Los datos contienen diferentes características de los diamantes, como quilates, calidad de corte, color y precio: carat, cut, color, clarity, depth, table, price como columnas. Ahora, corte, claridad y color son variables categóricas, y x, y, z, profundidad, tabla y precio son variables continuas. Mientras que las variables categóricas toman como valores categorías/nombres únicos, los valores continuos toman números reales como valores.

  • Contar el número de filas y columnas en el DataFrame utilizando la función shape

diamonds_df.shape
(53940, 10)
  • Resumir las columnas utilizando describe() para obtener la distribución de las variables, incluyendo la media, la mediana, el mínimo, el máximo y los diferentes cuartiles

diamonds_df.describe()
carat depth table price x y z
count 53940.000000 53940.000000 53940.000000 53940.000000 53940.000000 53940.000000 53940.000000
mean 0.797940 61.749405 57.457184 3932.799722 5.731157 5.734526 3.538734
std 0.474011 1.432621 2.234491 3989.439738 1.121761 1.142135 0.705699
min 0.200000 43.000000 43.000000 326.000000 0.000000 0.000000 0.000000
25% 0.400000 61.000000 56.000000 950.000000 4.710000 4.720000 2.910000
50% 0.700000 61.800000 57.000000 2401.000000 5.700000 5.710000 3.530000
75% 1.040000 62.500000 59.000000 5324.250000 6.540000 6.540000 4.040000
max 5.010000 79.000000 95.000000 18823.000000 10.740000 58.900000 31.800000
  • Esto funciona para las variables continuas. Sin embargo, para las variables categóricas, necesitamos utilizar el parámetro include=object.

diamonds_df.describe(include=object)
cut color clarity
count 53940 53940 53940
unique 5 7 8
top Ideal G SI1
freq 21551 11292 13065
  • Para obtener información sobre el conjunto de datos, utilice el método info():

diamonds_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 53940 entries, 0 to 53939
Data columns (total 10 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   carat    53940 non-null  float64
 1   cut      53940 non-null  object 
 2   color    53940 non-null  object 
 3   clarity  53940 non-null  object 
 4   depth    53940 non-null  float64
 5   table    53940 non-null  float64
 6   price    53940 non-null  int64  
 7   x        53940 non-null  float64
 8   y        53940 non-null  float64
 9   z        53940 non-null  float64
dtypes: float64(6), int64(1), object(3)
memory usage: 4.1+ MB
  • Podemos acceder a la columna corte del DataFrame diamonds_df con diamonds_df.cut o diamonds_df[‘cut’]

  • Ahora, ¿qué tal si seleccionamos todas las filas correspondientes a los diamantes que tienen la talla Ideal y almacenarlas en un DataFrame separado? Podemos seleccionarlas utilizando la función loc para seleccionarlos:

diamonds_low_df = diamonds_df.loc[diamonds_df['cut']=='Ideal']
diamonds_low_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
11 0.23 Ideal J VS1 62.8 56.0 340 3.93 3.90 2.46
13 0.31 Ideal J SI2 62.2 54.0 344 4.35 4.37 2.71
16 0.30 Ideal I SI2 62.0 54.0 348 4.31 4.34 2.68
39 0.33 Ideal I SI2 61.8 55.0 403 4.49 4.51 2.78

Ejercicio 3: Añadir nuevas columnas al DataFrame

  • En este ejercicio, vamos a añadir nuevas columnas al conjunto de datos de diamantes en la biblioteca pandas. Empezaremos con la adición simple de columnas y luego avanzaremos y veremos la adición condicional de columnas. Para ello, vamos a seguir los siguientes pasos:

  • Cargue la biblioteca pandas

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Añade una columna price_per_carat al DataFrame. En este ejemplo el precio por quilates. Del mismo modo, también podemos utilizar la suma, la resta y otros operadores matemáticos sobre dos columnas numéricas.

diamonds_df['price_per_carat'] = diamonds_df['price']/diamonds_df['carat']
  • Llame a la función head de DataFrame para comprobar si la nueva columna se ha añadido como como se esperaba:

diamonds_df.head()
carat cut color clarity depth table price x y z price_per_carat
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43 1417.391304
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31 1552.380952
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31 1421.739130
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63 1151.724138
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75 1080.645161
  • Ahora, veremos la adición condicional de columnas. Vamos a intentar añadir una columna basada en el valor de price_per_carat, digamos que todo lo que sea más de 3500 como alto (codificado como 1) y todo lo que sea inferior a 3500 como bajo (codificado como 0).

import numpy as np

diamonds_df['price_per_carat_is_high'] = np.where(diamonds_df['price_per_carat'] > 3500, 1, 0)
diamonds_df.tail()
carat cut color clarity depth table price x y z price_per_carat price_per_carat_is_high
53935 0.72 Ideal D SI1 60.8 57.0 2757 5.75 5.76 3.50 3829.166667 1
53936 0.72 Good D SI1 63.1 55.0 2757 5.69 5.75 3.61 3829.166667 1
53937 0.70 Very Good D SI1 62.8 60.0 2757 5.66 5.68 3.56 3938.571429 1
53938 0.86 Premium H SI2 61.0 58.0 2757 6.15 6.12 3.74 3205.813953 0
53939 0.75 Ideal D SI2 62.2 55.0 2757 5.83 5.87 3.64 3676.000000 1

Ejercicio 4: Aplicación de funciones a las columnas de DataFrame

  • En este ejercicio, consideraremos un escenario en el que el precio de los diamantes ha aumentado y queremos aplicar un factor de incremento de 1.3 al precio de todos los diamantes en nuestro registro. Podemos conseguirlo aplicando una sencilla función. A continuación, redondearemos el precio de los diamantes hasta su tope. Para ello, vamos a seguir los siguientes pasos

  • Cargue la biblioteca pandas

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Aplique una función simple en las columnas utilizando el siguiente código:

diamonds_df['price'] = diamonds_df['price']*1.3
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 423.8 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 423.8 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 425.1 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 434.2 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 435.5 4.34 4.35 2.75
  • Aplicar la función math.ceil para redondear el precio de los diamantes hasta su tope

import math

diamonds_df['rounded_price'] = diamonds_df['price'].apply(math.ceil)
diamonds_df.head()
carat cut color clarity depth table price x y z rounded_price
0 0.23 Ideal E SI2 61.5 55.0 423.8 3.95 3.98 2.43 424
1 0.21 Premium E SI1 59.8 61.0 423.8 3.89 3.84 2.31 424
2 0.23 Good E VS1 56.9 65.0 425.1 4.05 4.07 2.31 426
3 0.29 Premium I VS2 62.4 58.0 434.2 4.20 4.23 2.63 435
4 0.31 Good J SI2 63.3 58.0 435.5 4.34 4.35 2.75 436
  • Puede haber ocasiones en las que tenga que escribir su propia función para realizar la tarea que desea llevar a cabo.

  • Por ejemplo, digamos que quiere añadir otra columna al DataFrame indicando el precio redondeado de los diamantes al múltiplo de 100 (igual o superior al precio).

  • Utilice la función lambda como sigue para redondear el precio de los diamantes al múltiplo de 100 más cercano

import math

diamonds_df['rounded_price_to_100multiple'] = diamonds_df['price'].apply(lambda x: 100*math.ceil(x/100))
diamonds_df.head()
carat cut color clarity depth table price x y z rounded_price rounded_price_to_100multiple
0 0.23 Ideal E SI2 61.5 55.0 423.8 3.95 3.98 2.43 424 500
1 0.21 Premium E SI1 59.8 61.0 423.8 3.89 3.84 2.31 424 500
2 0.23 Good E VS1 56.9 65.0 425.1 4.05 4.07 2.31 426 500
3 0.29 Premium I VS2 62.4 58.0 434.2 4.20 4.23 2.63 435 500
4 0.31 Good J SI2 63.3 58.0 435.5 4.34 4.35 2.75 436 500
  • Por supuesto, no todas las funciones pueden ser escritas en una sola línea y es importante saber cómo incluir funciones definidas por el usuario en la función apply. Vamos a escribir el mismo código con una función definida por el usuario para ilustrarlo.

import math

def get_100_multiple_ceil(x):
    y = 100*math.ceil(x/100)
    return y
 
diamonds_df['rounded_price_to_100multiple']=diamonds_df['price'].apply(get_100_multiple_ceil)
diamonds_df.head()
carat cut color clarity depth table price x y z rounded_price rounded_price_to_100multiple
0 0.23 Ideal E SI2 61.5 55.0 423.8 3.95 3.98 2.43 424 500
1 0.21 Premium E SI1 59.8 61.0 423.8 3.89 3.84 2.31 424 500
2 0.23 Good E VS1 56.9 65.0 425.1 4.05 4.07 2.31 426 500
3 0.29 Premium I VS2 62.4 58.0 434.2 4.20 4.23 2.63 435 500
4 0.31 Good J SI2 63.3 58.0 435.5 4.34 4.35 2.75 436 500

Ejercicio 5: Aplicación de funciones en varias columnas

  • Supongamos que estamos interesados en comprar diamantes que tengan Ideal cut y color D (totalmente incoloro). Este ejercicio consiste en añadir una nueva columna, desired, al DataFrame, cuyo valor será yes si se cumplen nuestros criterios y no si no se cumplen. Veamos cómo lo hacemos:

  • Cargue la biblioteca pandas

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df_exercise = pd.read_csv(diamonds_url)
diamonds_df_exercise.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Write a function to determine whether a record, x, is desired or not:

def is_desired(x):
    bool_var = 'yes' if (x['cut']=='Ideal' and x['color']=='D') else 'no'
    return bool_var
  • Utilice la función apply para añadir la nueva columna, desired:

diamonds_df_exercise['desired'] = diamonds_df_exercise.apply(is_desired, axis = 'columns')
diamonds_df_exercise.tail()
carat cut color clarity depth table price x y z desired
53935 0.72 Ideal D SI1 60.8 57.0 2757 5.75 5.76 3.50 yes
53936 0.72 Good D SI1 63.1 55.0 2757 5.69 5.75 3.61 no
53937 0.70 Very Good D SI1 62.8 60.0 2757 5.66 5.68 3.56 no
53938 0.86 Premium H SI2 61.0 58.0 2757 6.15 6.12 3.74 no
53939 0.75 Ideal D SI2 62.2 55.0 2757 5.83 5.87 3.64 yes

Ejercicio 6: Eliminación de columnas de un DataFrame

  • Por último, vamos a ver cómo eliminar columnas de un DataFrame de pandas. Por ejemplo, borraremos las columnas rounded_price y rounded_price_to_100multiple

  • Cargue la biblioteca pandas

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Añadir la columna price_per_carat al DataFrame

diamonds_df['price_per_carat'] = diamonds_df['price']/diamonds_df['carat']
diamonds_df.head()
carat cut color clarity depth table price x y z price_per_carat
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43 1417.391304
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31 1552.380952
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31 1421.739130
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63 1151.724138
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75 1080.645161
  • Utilice la función np.where del paquete numpy de Python:

import numpy as np

diamonds_df['price_per_carat_is_high'] = np.where(diamonds_df['price_per_carat'] > 3500, 1, 0)
diamonds_df.tail()
carat cut color clarity depth table price x y z price_per_carat price_per_carat_is_high
53935 0.72 Ideal D SI1 60.8 57.0 2757 5.75 5.76 3.50 3829.166667 1
53936 0.72 Good D SI1 63.1 55.0 2757 5.69 5.75 3.61 3829.166667 1
53937 0.70 Very Good D SI1 62.8 60.0 2757 5.66 5.68 3.56 3938.571429 1
53938 0.86 Premium H SI2 61.0 58.0 2757 6.15 6.12 3.74 3205.813953 0
53939 0.75 Ideal D SI2 62.2 55.0 2757 5.83 5.87 3.64 3676.000000 1
  • Aplicar una función compleja para redondear el precio de los diamantes hasta su tope:

import math

diamonds_df['rounded_price'] = diamonds_df['price'].apply(math.ceil)
diamonds_df.head()
carat cut color clarity depth table price x y z price_per_carat price_per_carat_is_high rounded_price
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43 1417.391304 0 326
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31 1552.380952 0 326
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31 1421.739130 0 327
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63 1151.724138 0 334
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75 1080.645161 0 335
  • Escribe un código para crear una función definida por el usuario:

import math

def get_100_multiple_ceil(x):
    y = math.ceil(x/100)*100
    return y
 
diamonds_df['rounded_price_to_100multiple']=diamonds_df['price'].apply(get_100_multiple_ceil)
diamonds_df.head()
carat cut color clarity depth table price x y z price_per_carat price_per_carat_is_high rounded_price rounded_price_to_100multiple
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43 1417.391304 0 326 400
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31 1552.380952 0 326 400
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31 1421.739130 0 327 400
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63 1151.724138 0 334 400
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75 1080.645161 0 335 400
  • Eliminar las columnas rounded_price y rounded_price_to_100multiple utilizando la función drop:

diamonds_df = diamonds_df.drop(columns = ['rounded_price', 'rounded_price_to_100multiple'])
diamonds_df.head()
carat cut color clarity depth table price x y z price_per_carat price_per_carat_is_high
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43 1417.391304 0
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31 1552.380952 0
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31 1421.739130 0
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63 1151.724138 0
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75 1080.645161 0

Ejercicio 7: Escribir un DataFrame en un archivo

  • En este ejercicio, escribiremos un DataFrame de diamantes en un archivo .csv. Para ello, utilizaremos el siguiente código:

  • Cargue la biblioteca pandas

import pandas as pd
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Escriba el conjunto de datos de los diamantes en un archivo .csv:

diamonds_df.to_csv('diamonds_modified.csv')
  • Por defecto, la función to_csv genera un archivo que incluye las cabeceras de las columnas y los números de las filas. así como los números de fila. Añade un parámetro index=False para excluir los números de fila:

diamonds_df.to_csv('diamonds_modified.csv', index = False)
  • Ahora que tenemos una idea básica de cómo cargar y manejar los datos en un objeto DataFrame de pandas, vamos a empezar a hacer algunos gráficos simples a partir de los datos.

  • matplotlib es una biblioteca de trazado disponible en la mayoría de las distribuciones de Python y es la es la base de varios paquetes de ploteo, incluyendo la funcionalidad de ploteo incorporada en pandas y seaborn. matplotlib permite controlar todos los aspectos de una figura y es conocido por ser muy detallado.

Exercise 8: Trazado y análisis de un histograma

  • En este ejercicio, crearemos un histograma de la frecuencia de los diamantes en el conjunto de datos con sus respectivas especificaciones de carat (quilates) en el eje \(x\):

  • Cargue la biblioteca pandas

import pandas as pd
import seaborn as sns
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Trazar un histograma utilizando el conjunto de datos de diamantes donde el eje x axis = carat. El eje \(y\) de este gráfico indica el número de diamantes del conjunto de datos con la especificación de carat en el eje \(x\).

diamonds_df.hist(column='carat')
array([[<AxesSubplot:title={'center':'carat'}>]], dtype=object)
_images/.~notebooks_105_1.png
  • La función hist tiene un parámetro llamado bins, que se refiere literalmente al número de intervalos de igual tamaño en los que se dividen los puntos de datos. Por defecto el parámetro bins está fijado en 10 en pandas. Podemos cambiarlo por un número diferente diferente, si lo deseamos.

diamonds_df.hist(column = 'carat', bins = 50)
array([[<AxesSubplot:title={'center':'carat'}>]], dtype=object)
_images/.~notebooks_107_1.png
  • Ahora, veamos la misma función utilizando seaborn. Note que pandas establece el parámetro bins a un valor por defecto de 10, pero seaborn infiere un bin de tamaño apropiado basado en la distribución estadística del conjunto de datos.

import seaborn as sns

sns.distplot(diamonds_df.carat)
<AxesSubplot:xlabel='carat', ylabel='Density'>
_images/.~notebooks_109_1.png
  • Por defecto, la función distplot también incluye una curva suavizada sobre el histograma, llamada estimación de la densidad del kernel (KDE). Si queremos eliminar el KDE y mirar sólo el histograma, podemos utilizar el parámetro kde=False.

sns.distplot(diamonds_df.carat, kde = False)
<AxesSubplot:xlabel='carat'>
_images/.~notebooks_111_1.png
  • Una transformación logarítmica ayuda a identificar más tendencias. Por ejemplo, en el siguiente gráfico, el eje \(x\) muestra los valores transformados en logaritmos de la variable del precio, y vemos que hay dos picos que indican dos tipos de diamantes: uno con un precio alto y otro con un precio bajo

import numpy as np
sns.distplot(np.log(diamonds_df.price))
<AxesSubplot:xlabel='price', ylabel='Density'>
_images/.~notebooks_113_1.png

Qué valores de las características son más frecuentes en el conjunto de datos (en este caso, hay un pico en torno a 6.8 y otro pico entre 8.5 y 9, nótese que log(price) = valores, en este caso

Exercise 9: Creación de un gráfico de barras y cálculo de la distribución del precio medio

  • En este ejercicio, aprenderemos a crear una tabla utilizando la función pandas crosstab. Utilizaremos una tabla para generar un gráfico de barras. A continuación, exploraremos un gráfico de barras generado con la biblioteca seaborn y calcularemos la distribución del precio medio. Para ello, vamos a realizar los siguientes pasos

  • Cargue la biblioteca pandas

import pandas as pd
import seaborn as sns
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Imprime los valores únicos de la columna corte:

diamonds_df.cut.unique()
array(['Ideal', 'Premium', 'Good', 'Very Good', 'Fair'], dtype=object)
  • Imprime los valores únicos de la columna claridad:

diamonds_df.clarity.unique()
array(['SI2', 'SI1', 'VS1', 'VS2', 'VVS2', 'VVS1', 'I1', 'IF'],
      dtype=object)
  • unique() devuelve un array. Hay cinco cualidades únicas de cut y ocho valores únicos en clarity. El número de valores únicos se puede obtener utilizando nunique() en `pandas.

  • Para obtener los recuentos de diamantes de cada calidad de cut, primero creamos una tabla utilizando la función pandas crosstab():

cut_count_table = pd.crosstab(index = diamonds_df['cut'], columns = 'count')
cut_count_table
col_0 count
cut
Fair 1610
Good 4906
Ideal 21551
Premium 13791
Very Good 12082
  • Pase estos recuentos a otra función pandas, plot(kind=’bar’):

cut_count_table.plot(kind = 'bar')
<AxesSubplot:xlabel='cut'>
_images/.~notebooks_129_1.png

Vemos que la mayoría de los diamantes del conjunto de datos son de la calidad de corte Ideal, seguidos de Premium, Very Good, Good y Fair. Ahora, veamos cómo generar el mismo gráfico utilizando seaborn.

  • Generate the same bar plot using seaborn

sns.catplot("cut", data = diamonds_df, aspect = 1.5, kind = "count", color = "b")
<seaborn.axisgrid.FacetGrid at 0x7f57aeef2e10>
_images/.~notebooks_132_1.png

Observe cómo la función catplot() no requiere que creemos la tabla de recuento intermedia (utilizando pd.crosstab()), y reduce un paso en el proceso de trazado.

  • A continuación, se muestra cómo se obtiene la distribución del precio medio de las diferentes calidades de cut utilizando seaborn

import seaborn as sns
from numpy import median, mean

sns.set(style = "whitegrid")
ax = sns.barplot(x = "cut", y = "price", data = diamonds_df, estimator = mean)
_images/.~notebooks_135_0.png

Aquí, las líneas negras (barras de error) de los rectángulos indican la incertidumbre (o dispersión de los valores) en torno a la estimación de la media. Las funciones mencionadas van mucho más allá de un simple recuento: aplican una función que calcula una medida de tendencia central (por defecto es el valor medio) y muestran, aplicando bootstrapping, el intervalo de confianza del 95% para dicha medida. Por defecto, este valor está fijado en un 95% de confianza. ¿Cómo lo cambiamos? Utilizando el parámetro ci=68, por ejemplo, lo fijamos en el 68%. También podemos representar la desviación estándar en los precios utilizando ci=sd.

  • Reordenar las barras del eje x utilizando el orden:

ax = sns.barplot(x = "cut", y = "price", data = diamonds_df, estimator = mean, ci = 68, 
                 order=['Ideal','Good','Very Good','Fair','Premium'])
_images/.~notebooks_138_0.png

Exercise 10: Creación de gráficos de barras agrupados por una característica específica

  • En este ejercicio, utilizaremos el conjunto de datos de los diamantes para generar la distribución de los precios con respecto al color para cada calidad de corte. En el ejercicio 7, vimos la distribución de precios para diamantes de diferentes calidades de talla. Ahora, nos gustaría ver la variación de cada color:

  • Cargue la biblioteca pandas

import pandas as pd
import seaborn as sns
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.tail()
carat cut color clarity depth table price x y z
53935 0.72 Ideal D SI1 60.8 57.0 2757 5.75 5.76 3.50
53936 0.72 Good D SI1 63.1 55.0 2757 5.69 5.75 3.61
53937 0.70 Very Good D SI1 62.8 60.0 2757 5.66 5.68 3.56
53938 0.86 Premium H SI2 61.0 58.0 2757 6.15 6.12 3.74
53939 0.75 Ideal D SI2 62.2 55.0 2757 5.83 5.87 3.64
  • Utilice el parámetro hue para trazar grupos anidados:

ax = sns.barplot(x = "cut", y = "price", hue = 'color', data = diamonds_df)
_images/.~notebooks_146_0.png

Aquí podemos observar que los patrones de precios de los diamantes de diferentes colores son similares para cada calidad de talla.

Exercise 11: Cómo ajustar los parámetros de un gráfico de barras agrupadas

  • En este ejercicio, modificaremos los parámetros de los gráficos, por ejemplo, hue, de un gráfico de barras agrupadas. Veremos cómo colocar las leyendas y las etiquetas de los ejes en los lugares adecuados y también exploraremos la función de rotación

  • Cargue la biblioteca pandas

import pandas as pd
import seaborn as sns
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
ax = sns.barplot(x = "cut", y = "price", hue = 'color', data = diamonds_df)
_images/.~notebooks_154_0.png
ax = sns.barplot(x='cut', y='price', hue='color', data=diamonds_df)
ax.legend(loc='upper right', ncol=4)
<matplotlib.legend.Legend at 0x7f57ae661d68>
_images/.~notebooks_155_1.png

En la llamada anterior a ax.legend(), el parámetro ncol denota el número de columnas en las que deben organizarse los valores de la leyenda, y el parámetro loc especifica la ubicación de la leyenda y puede tomar cualquiera de los ocho valores 'upper left', 'upper right', 'lower left', 'lower right'.

  • Para modificar las etiquetas de los ejes \(𝑥\) y \(𝑦\), introduzca el siguiente código

ax = sns.barplot(x='cut', y='price', hue='color', data=diamonds_df)
ax.legend(loc='upper right', ncol=4)
ax.set_xlabel('Cut', fontdict={'fontsize' : 12})
ax.set_ylabel('Price', fontdict={'fontsize' : 12})
Text(0, 0.5, 'Price')
_images/.~notebooks_158_1.png
  • Del mismo modo, utilice esto para modificar el tamaño de la fuente y la rotación del eje \(x\) de la garrapata etiquetas:

ax = sns.barplot(x='cut', y='price', hue='color', data=diamonds_df)
ax.legend(loc='upper right',ncol=4)
ax.set_xticklabels(ax.get_xticklabels(), fontsize=13, rotation=45)
ax.set_xlabel('Cut', fontdict={'fontsize' : 12})
ax.set_ylabel('Price', fontdict={'fontsize' : 12})
Text(0, 0.5, 'Price')
_images/.~notebooks_160_1.png

La función de rotación es especialmente útil cuando las etiquetas de ticks son largas y se amontonan en el eje \(x\).

Exercise 12: Anotar un gráfico de barras

  • En este ejercicio, anotaremos un gráfico de barras, generado con la función catplot de seaborn, utilizando una nota justo encima del gráfico.

  • Cargue la biblioteca pandas

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
  • Leer los archivos de la URL en el DataFrame de pandas

diamonds_df = pd.read_csv(diamonds_url)
diamonds_df.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
1 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 2.31
2 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 2.31
3 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 2.63
4 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 2.75
  • Generar un gráfico de barras utilizando la función catplot de la biblioteca seaborn

ax = sns.catplot("cut", data=diamonds_df, aspect=1.5, kind="count", color="b")
_images/.~notebooks_169_0.png
  • Anote la columna que pertenece a la categoría Ideal:

ideal_group = diamonds_df.loc[diamonds_df['cut']=='Ideal']
ideal_group.head()
carat cut color clarity depth table price x y z
0 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 2.43
11 0.23 Ideal J VS1 62.8 56.0 340 3.93 3.90 2.46
13 0.31 Ideal J SI2 62.2 54.0 344 4.35 4.37 2.71
16 0.30 Ideal I SI2 62.0 54.0 348 4.31 4.34 2.68
39 0.33 Ideal I SI2 61.8 55.0 403 4.49 4.51 2.78
  • Encuentre la ubicación de la coordenada \(x\) donde debe colocarse la anotación:

x = ideal_group.index.tolist()[0]
  • Encuentre la ubicación de la coordenada \(y\) donde debe colocarse la anotación:

y = len(ideal_group)
  • Imprime la ubicación de las coordenadas \(x\) e \(y\):

print(x)
print(y)
0
21551
  • Anota la gráfica con una nota:

sns.catplot("cut", data=diamonds_df, aspect=1.5, kind="count", color="b")
plt.annotate('excellent polish and symmetry ratings;\nreflects almost all the light that enters it', 
             xy=(x,y), xytext=(x+0.3, y+2000), arrowprops=dict(facecolor='red'))
Text(0.3, 23551, 'excellent polish and symmetry ratings;\nreflects almost all the light that enters it')
_images/.~notebooks_179_1.png
  • Ahora, parece que hay muchos parámetros en la función de anotación. La documentación oficial de Matplotlib cubre todos los detalles

Tarea 1.1

  • Trabajaremos con el conjunto de datos de 120 años de historia olímpica adquirido por Randi Griffin en Randi-Griffin y puesto a disposición en athlete_events. - Su tarea consiste en identificar los cinco deportes más importantes según el mayor número de medallas otorgadas en el año 2016, y luego realizar el siguiente análisis:

  1. Genere un gráfico que indique el número de medallas concedidas en cada uno de los cinco principales deportes en 2016.

  2. Trace un gráfico que represente la distribución de la edad de los ganadores de medallas en los cinco principales deportes en 2016.

  3. Descubre qué equipos nacionales ganaron el mayor número de medallas en los cinco principales deportes en 2016.

  4. Observe la tendencia del peso medio de los atletas masculinos y femeninos ganadores en los cinco principales deportes en 2016

  • Pasos principales

  1. Descargue el conjunto de datos y formatéelo como un DataFrame de pandas.

  2. Filtra el DataFrame para incluir solo las filas correspondientes a los ganadores de medallas de 2016.

  3. Descubre las medallas concedidas en 2016 en cada deporte.

  4. Enumera los cinco deportes más importantes en función del mayor número de medallas concedidas. Filtra el DataFrame una vez más para incluir solo los registros de los cinco deportes principales en 2016.

  5. Genere un gráfico de barras con los recuentos de registros correspondientes a cada uno de los cinco deportes principales.

  6. Generar un histograma para la característica Edad de todos los ganadores de medallas en los cinco deportes principales (2016).

  7. Genera un gráfico de barras que indique cuántas medallas ganó el equipo de cada país en los cinco deportes principales en 2016.

  8. Genere un gráfico de barras que indique el peso medio de los jugadores, clasificados en función del género, que ganaron en los cinco principales deportes en 2016.

Visualización estática

  • Este capítulo es un manual sobre los diferentes tipos de visualización estática y los contextos en los que son más eficaces. Utilizando seaborn, aprenderá a crear una variedad de variedad de gráficos y a seleccionar el tipo correcto de visualización para la representación más adecuada de sus datos.

  • En esta sección, estudiaremos el contexto de los gráficos que presentan patrones globales en los datos, como por ejemplo:

  1. Gráficos que muestran la varianza de las características individuales de los datos, como los histogramas

  2. Gráficos que muestran cómo varían las diferentes características presentes en los datos entre sí, como los gráficos de dispersión, los gráficos de líneas y los mapas de calor.

  • Scatter plot

  1. Un gráfico de dispersión es un gráfico simple que presenta los valores de dos características en un conjunto de datos.

  2. Cada punto de datos se representa mediante un punto con la coordenada \(x\) como valor de la primera característica y la coordenada \(y\) como valor de la segunda característica.

  3. Un gráfico de dispersión es una gran herramienta para aprender más sobre dos atributos numéricos.

  4. Los gráficos de dispersión pueden ayudar a descubrir las relaciones entre diferentes características de los datos, como el tiempo y las ventas, la ingesta de alimentos y las estadísticas de salud en varios contextos.

Ejercicio 13: Creación de un gráfico de dispersión estático

  • En este ejercicio, generaremos un gráfico de dispersión para examinar la relación entre el peso (weight) y el millaje (mpg) de los vehículos del conjunto de datos mpg. Para ello, vamos a seguir los siguientes pasos:

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

mpg_df = sns.load_dataset("mpg")
  • Generar un gráfico de dispersión utilizando la función scatterplot():

ax = sns.scatterplot(x="weight", y="mpg", data=mpg_df)
_images/.~notebooks_197_0.png

Observación: Nótese que el gráfico de dispersión muestra una disminución del mileage (mpg) con un aumento del weight. Es una visión útil de las relaciones entre las diferentes características del conjunto de datos.

Ejercicio 14: Creación de un gráfico hexagonal estático Binning

  • También existe una versión más elegante de los gráficos de dispersión, llamada hexagonal binning plot (hexbin plot). En este ejercicio, generaremos un diagrama de dispersión hexagonal para comprender mejor la relación entre el peso (weight) y el millaje (mileage (mpg)):

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

mpg_df = sns.load_dataset("mpg")
  • Trazar un gráfico hexbin usando jointplot con el tipo establecido en hex:

sns.set(style="ticks")
sns.jointplot(mpg_df.weight, mpg_df.mpg, kind="hex", color="#4CB391")
<seaborn.axisgrid.JointGrid at 0x7f57ae726390>
_images/.~notebooks_206_1.png

Observación: Como puede observar, el histograma de los ejes superior y derecho representa la varianza de las características representadas por los ejes \(x\) e \(y\) respectivamente (mpg y weight, en este ejemplo). Además, es posible que haya notado en el gráfico de dispersión anterior que los datos se superponían fuertemente en ciertas áreas, ocultando la distribución real de las características. Los gráficos Hexbin son una buena herramienta de visualización utilizada cuando los datos son muy densos.

Ejercicio 15: Creación de un gráfico de contorno estático

  • Otra alternativa a los gráficos de dispersión cuando los puntos de datos están densamente poblados en regiones específicas es un gráfico de contorno. En este ejercicio, crearemos un gráfico de contorno para mostrar la relación entre weight y el mileage en el conjunto de datos mpg. Podremos ver que la relación entre weight y mileage es más fuerte cuando hay mayor volumen de datos

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

mpg_df = sns.load_dataset("mpg")
  • Crea un gráfico de contorno utilizando el método set_style

sns.set_style("white")
  • Generar un gráfico de estimación de la densidad del núcleo (KDE). Los dos primeros parámetros son matrices de \(X\) e \(Y\) coordenadas de los puntos de datos, el parámetro shade se establece en True para que los contornos se rellenen con un gradiente de color basado en el número de puntos de datos

sns.kdeplot(mpg_df.weight, mpg_df.mpg, shade=True)
<AxesSubplot:xlabel='weight', ylabel='mpg'>
_images/.~notebooks_217_1.png

Observación: En nuestro ejemplo de weight frente a mileage (mpg), el diagrama hexagonal y el diagrama de contorno indican que hay una determinada curva a lo largo de la cual la relación negativa entre el peso y el kilometraje es más fuerte, como es evidente por el mayor número de puntos de datos. La relación negativa se vuelve relativamente más débil a medida que nos alejamos de la curva (menos volumen de datos).

Ejercicio 16: Creación de un gráfico de líneas estáticas

  • Los gráficos de líneas representan la información como una serie de puntos de datos conectados por segmentos de líneas rectas. Son útiles para indicar la relación entre una característica numérica discreta (en el eje \(x\)), como model_year, y una característica numérica continua (en el eje \(y\)), como mpg del conjunto de datos mpg. En este ejercicio, crearemos un gráfico de dispersión para un par de características diferentes, model_year y mpg.

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

mpg_df = sns.load_dataset("mpg")
  • Slecciones el estilo para la figura con set_style

sns.set_style("white")
  • Crear un gráfico de dispersión bidimensional

ax1 = sns.scatterplot(x="model_year", y="mpg", data=mpg_df)
_images/.~notebooks_228_0.png

Observación: En este ejemplo, vemos que la característica model_year sólo toma valores discretos entre 70 y 82. Ahora, cuando tenemos una característica numérica discreta como esta (modelo_año), dibujar un gráfico de líneas uniendo los puntos de datos es una buena idea. Podemos dibujar un simple gráfico de líneas que muestre la relación entre año_modelo y kilometraje con el siguiente código.

  • Dibuja un gráfico lineal simple para mostrar la relación entre model_year y mileage

ax = sns.lineplot(x="model_year", y="mpg", data=mpg_df)
_images/.~notebooks_231_0.png

Observación: Como podemos ver, los puntos conectados por la línea sólida representan la media de la característica del eje \(y\) en la coordenada \(x\) correspondiente. El área sombreada alrededor de la línea muestra el intervalo de confianza para la característica del eje \(y\) (por defecto, seaborn establece el intervalo de confianza del 95%). El parámetro ci puede utilizarse para cambiar a un intervalo de confianza diferente.

  • Cambiar el intervalo de confianza a 68

sns.lineplot(x="model_year", y="mpg", data=mpg_df, ci=68)
<AxesSubplot:xlabel='model_year', ylabel='mpg'>
_images/.~notebooks_234_1.png

Observación: Como podemos ver en el gráfico anterior, el intervalo de confianza del 68% se traduce en un rango de valores de características en el que están presentes el 68% de los puntos de datos. Los gráficos de líneas son excelentes técnicas de visualización para escenarios en los que tenemos datos que cambian con el tiempo, eje \(x\), podría representar la fecha o el tiempo, y el gráfico ayudaría a visualizar cómo un valor varía a lo largo de ese periodo

Ejercicio 17: Presentación de datos a través del tiempo con múltiples gráficos de líneas

  • En este ejemplo, veremos cómo presentar los datos a través del tiempo con múltiples gráficos de líneas. En este ejemplo utilizamos el conjunto de datos de vuelos

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

flights_df = sns.load_dataset("flights")
print(flights_df.head())
   year month  passengers
0  1949   Jan         112
1  1949   Feb         118
2  1949   Mar         132
3  1949   Apr         129
4  1949   May         121

Supongamos que quiere observar cómo varía el número de pasajeros entre meses en diferentes años. ¿Cómo mostraría esta información? Una opción es dibujar varios gráficos de líneas en una sola figura.

  • Crear varias gráficas para los meses de diciembre y enero

fig,ax=plt.subplots()
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Jan'], color='green')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Feb'], color='red')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Mar'], color='blue')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Apr'], color='cyan')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='May'], color='pink')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Jun'], color='black')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Jul'], color='grey')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Aug'], color='yellow')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Sep'], color='turquoise')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Oct'], color='orange')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Nov'], color='darkgreen')
ax = sns.lineplot(x="year", y="passengers", data=flights_df[flights_df['month']=='Dec'], color='darkred')
_images/.~notebooks_244_0.png

Observación Con este ejemplo de 12 gráficos de líneas, podemos ver cómo una figura con demasiados gráficos de líneas rápidamente comienza a abarrotarse y a confundirse. Por lo tanto, para ciertos escenarios, los gráficos de líneas no son no son atractivos ni útiles. Entonces, ¿cuál es la alternativa para nuestro caso de uso? Lo veremos en el siguiente ejercicio

Ejercicio 18: Creación y exploración de un mapa de calor estático

  • Un heatmap es una representación visual de una característica numérica continua específica en función de otras dos características discretas (ya sea una categórica o una numérica discreta) en el conjunto de datos. En este ejercicio, exploraremos y crearemos un mapa de calor. Utilizaremos el conjunto de datos de vuelos de la biblioteca seaborn para generar un mapa de calor que represente el número de pasajeros por mes en los años 1949-1960

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

flights_df = sns.load_dataset("flights")
print(flights_df.head())
   year month  passengers
0  1949   Jan         112
1  1949   Feb         118
2  1949   Mar         132
3  1949   Apr         129
4  1949   May         121
  • Ahora tenemos que hacer pivotar el conjunto de datos sobre las variables requeridas utilizando la función pivot() antes de generar el mapa de calor. La función pivot toma primero como argumentos la característica que se mostrará en filas, luego la que se muestra en columnas y, por último, la característica cuya variación nos interesa observar. Utiliza los valores únicos de los índices/columnas especificados para formar los ejes del DataFrame resultante

df_pivoted = flights_df.pivot("month", "year", "passengers")
ax = sns.heatmap(df_pivoted)
_images/.~notebooks_253_0.png

Observación: Aquí podemos observar que el número total de vuelos anuales aumentó de forma constante desde 1949 a 1960. Además, los meses de julio y agosto parecen tener el mayor número de vuelos (en comparación con el resto de los meses) en todos los años de observación.

  • Utilice la opción clustermap para agrupar filas y columnas:

ax = sns.clustermap(df_pivoted, col_cluster=False, row_cluster=True)
_images/.~notebooks_256_0.png

Observación: Nótese que el orden de los meses se ha reordenado en los gráficos, pero algunos meses (por ejemplo, julio y agosto) se han mantenido juntos debido a sus tendencias similares. Tanto en julio como en agosto, el número de vuelos aumentó de forma relativamente más drástica en los últimos años hasta 1960. ¿Cómo se calcula la similitud entre filas y columnas? La respuesta es que depende de la métrica de distancia

  • Establecer la métrica como euclidiana

ax = sns.clustermap(df_pivoted, col_cluster=False)
_images/.~notebooks_259_0.png
  • Cambiar la métrica a correlación

ax = sns.clustermap(df_pivoted, row_cluster=False, metric='correlation')
_images/.~notebooks_261_0.png

Observación: Al leer sobre la métrica de la distancia, aprendemos que define la distancia entre dos filas/columnas. Sin embargo, si nos fijamos bien, vemos que el mapa de calor también agrupa no sólo filas o columnas individuales, sino también grupos de filas y columnas. filas o columnas individuales. Aquí es donde entra en juego la vinculación.

Ejercicio 19: Creación de vínculos en mapas térmicos estáticos

  1. Si definimos la distancia entre dos clusters como la distancia entre los dos puntos de los clusters más cercanos entre sí, la regla se denomina enlace único (single linkage).

  2. Si la regla es definir la distancia entre dos clusters como la distancia entre los puntos más alejados entre sí, se denomina vinculación completa (complete linkage).

  3. Si la regla es definir la distancia como la media de todos los posibles pares de filas en los dos clústeres, se denomina vinculación media (average linkage).

  • En este ejercicio, generaremos un mapa de calor y comprenderemos el concepto de enlace único, completo y promedio en los mapas de calor utilizando el conjunto de datos flights.

  • Abra un cuaderno Jupyter e importe los módulos de Python necesarios:

import seaborn as sns
  • Importe el conjunto de datos de seaborn:

flights_df = sns.load_dataset("flights")
print(flights_df.head())
   year month  passengers
0  1949   Jan         112
1  1949   Feb         118
2  1949   Mar         132
3  1949   Apr         129
4  1949   May         121
  • Ahora necesitamos pivotar el conjunto de datos en las variables requeridas utilizando la función pivot() antes de generar el mapa de calor:

df_pivoted = flights_df.pivot("month", "year", "passengers")
ax = sns.heatmap(df_pivoted)
_images/.~notebooks_271_0.png
  • Enlaza los mapas de calor utilizando el código que sigue

ax = sns.clustermap(df_pivoted, col_cluster=False, metric='correlation', method='average')
ax = sns.clustermap(df_pivoted, row_cluster=False, metric='correlation', method='complete')
ax = sns.clustermap(df_pivoted, row_cluster=False, metric='correlation', method='single')
_images/.~notebooks_273_0.png _images/.~notebooks_273_1.png _images/.~notebooks_273_2.png

Observación Los mapas de calor también son una buena forma de visualizar lo que ocurre en un espacio 2D. Por ejemplo, pueden utilizarse para mostrar dónde hay más acción en el campo en un partido de fútbol. Del mismo modo, en un sitio web, los mapas de calor se pueden utilizar para mostrar las áreas que son más más frecuentadas por los usuarios.

Creación de gráficos para representar estadísticas

  • Cuando los conjuntos de datos son enormes, a veces resulta útil observar las estadísticas de resumen de una serie de características diferentes y hacerse una idea preliminar del conjunto de datos. Por ejemplo, las estadísticas de resumen de cualquier característica numérica incluyen medidas de tendencia central, como la media, y medidas de dispersión, como la desviación estándar. Los histogramas muestran la distribución de una característica dada en los datos, podemos hacer un gráfico un poco más informativo mostrando algunas estadísticas de resumen en el mismo gráfico.

Ejemplo 1: Histograma revisado

  • Importar los módulos de Python necesarios; cargar el conjunto de datos; elegir el número de intervalos y si la estimación de la densidad del kernel debe mostrarse o no; usar el color rojo para mostrar media utilizando una línea recta en el eje \(x\) (paralela al eje \(y\)); definir la ubicación de la leyenda:

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

mpg_df = sns.load_dataset("mpg")
ax = sns.distplot(mpg_df.weight, bins=50, kde=False)
plt.axvline(x=np.mean(mpg_df.weight), color='red', label='mean')
plt.axvline(x=np.median(mpg_df.weight), color='orange', label='median')
plt.legend(loc='upper right')
<matplotlib.legend.Legend at 0x7f57ae73a7b8>
_images/.~notebooks_279_1.png

Este histograma muestra la distribución de la característica de peso junto con la media y la mediana. Observe que la media no es igual a la mediana, lo que significa que la característica no está distribuida normalmente.

Ejercicio 20: Creación y exploración de un gráfico de caja

Los gráficos de caja son una forma excelente de examinar la relación entre las estadísticas de resumen de una característica numérica en relación con otras características categóricas. En este ejercicio crearemos un diagrama para establecer la relación entre model_year and mileage using the mpg dataset. We’ll analyze manufacturing efficiency and the mileage of vehicles over a period of years. To do so, let’s go through the following steps

  • Importe la libreria seaborn

import seaborn as sns
  • Cargue el dataset

mpg_df = sns.load_dataset("mpg")
mpg_df.head()
mpg cylinders displacement horsepower weight acceleration model_year origin name
0 18.0 8 307.0 130.0 3504 12.0 70 usa chevrolet chevelle malibu
1 15.0 8 350.0 165.0 3693 11.5 70 usa buick skylark 320
2 18.0 8 318.0 150.0 3436 11.0 70 usa plymouth satellite
3 16.0 8 304.0 150.0 3433 12.0 70 usa amc rebel sst
4 17.0 8 302.0 140.0 3449 10.5 70 usa ford torino
  • Crear un diagrama de cajas

sns.boxplot(x='model_year', y='mpg', data=mpg_df)
<AxesSubplot:xlabel='model_year', ylabel='mpg'>
_images/.~notebooks_288_1.png

Como podemos ver, los límites de la caja indican el rango intercuartil, el límite superior marca el cuartil del 25% y el límite inferior el cuartil del 75%. La línea horizontal dentro de la caja indica la mediana. Cualquier punto aislado fuera de los bigotes (las barras en forma de \(T\) por encima y por debajo de la caja) marca los valores atípicos, mientras que los propios bigotes muestran los valores mínimos y máximos que no son valores atípicos. Aparentemente, el millaje mejoró sustancialmente en los 80 en comparación con los 70.

  • Añadamos otra característica a nuestro mpg DataFrame que denote si el coche fue fabricado en los 70 o en los 80. Modifica el DataFrame mpg creando una nueva característica, model_decade

import numpy as np
mpg_df['model_decade'] = np.floor(mpg_df.model_year/10)*10
mpg_df['model_decade'] = mpg_df['model_decade'].astype(int)
mpg_df.tail()
mpg cylinders displacement horsepower weight acceleration model_year origin name model_decade
393 27.0 4 140.0 86.0 2790 15.6 82 usa ford mustang gl 80
394 44.0 4 97.0 52.0 2130 24.6 82 europe vw pickup 80
395 32.0 4 135.0 84.0 2295 11.6 82 usa dodge rampage 80
396 28.0 4 120.0 79.0 2625 18.6 82 usa ford ranger 80
397 31.0 4 119.0 82.0 2720 19.4 82 usa chevy s-10 80
  • Ahora, volvamos a dibujar nuestro gráfico de caja para ver la distribución de los millajes en las dos décadas

sns.boxplot(x='model_decade', y='mpg', data=mpg_df)
<AxesSubplot:xlabel='model_decade', ylabel='mpg'>
_images/.~notebooks_293_1.png

También podemos añadir otra característica, por ejemplo, la región de origen, y ver cómo afecta a la relación entre el kilometraje y el tiempo de fabricación, las dos características que hemos estado considerando hasta ahora

  • Use the hue parameter to group by origin

sns.boxplot(x='model_decade', y='mpg', data=mpg_df, hue='origin')
<AxesSubplot:xlabel='model_decade', ylabel='mpg'>
_images/.~notebooks_296_1.png

Como podemos ver, según el conjunto de datos de mpg, en los años 70 y principios de los 80, Europa y Japón produjeron coches con mejor millaje que los Estados Unidos.

Ejercicio 21: Creación de un gráfico de violín

  • ¿Y si pudiéramos obtener una pista sobre la distribución completa de una característica numérica específica agrupada por otras características categóricas? La tipo de técnica de visualización adecuada en este caso es un gráfico de violín. Un gráfico de violín es similar a un grafico de caja pero incluye más detalles sobre las variaciones de los datos. En este ejercicio, utilizaremos el conjunto de datos mpg y generaremos un gráfico de violín que represente la variación detallada del millaje (mpg) en función de model_decade y la región de origen

  • Importe la libreria seaborn

import seaborn as sns
  • Cargue el dataset

mpg_df = sns.load_dataset("mpg")
  • Generar el gráfico de violín utilizando la función violinplot en seaborn

import numpy as np

mpg_df['model_decade'] = np.floor(mpg_df.model_year/10)*10
mpg_df['model_decade'] = mpg_df['model_decade'].astype(int)
sns.violinplot(x='model_decade', y='mpg', data=mpg_df, hue='origin')
<AxesSubplot:xlabel='model_decade', ylabel='mpg'>
_images/.~notebooks_305_1.png
  • Podemos ver aquí que, durante los años 70, mientras que la mayoría de los vehículos de EE.UU. tenían un millaje medio de 19 mpg, los vehículos de Japón y Europa tenían millajes medios de alrededor de 27 y 25 mpg. Mientras que el kilometraje de los vehículos en Europa y Japón aumentó entre 7 y 8 puntos en los años 80, el kilometraje medio de los vehículos en EE.UU. seguía siendo similar al de los vehículos en Japón y Europa en la década anterior.

Tarea 1.2

Estadísticas: Seguiremos trabajando con el conjunto de datos de 120 años de historia olímpica adquirido por Randi Griffin en Randi Griffin

Como especialista en visualización, su tarea consiste en crear dos parcelas para los ganadores de medallas de 2016 de cinco deportes: atletismo, natación, remo, fútbol y hockey

  • Crea un gráfico utilizando una técnica de visualización adecuada que presente de la mejor manera posible el patrón global de las características de height y weight de los ganadores de medallas de 2016 de los cinco deportes.

  • Crea un gráfico utilizando una técnica de visualización adecuada que presente de la mejor manera posible la estadística de resumen para la altura y el peso de los jugadores que ganaron cada tipo de medalla (oro/plata/bronce) en los datos.

Utilizar su creatividad y sus habilidades para sacar conclusiones importantes de los datos

Pasos importantes

  • Descargue el conjunto de datos y formatéelo como un pandas DataFrame

  • Filtrar el DataFrame para incluir únicamente las filas correspondientes a los ganadores de medallas de 2016 en los deportes mencionados en la descripción de la actividad

  • Observe las características del conjunto de datos y anote su tipo de datos: ¿son categóricos o numéricos?

  • Evaluar cuál sería la visualización adecuada para que un patrón global represente las características de height y weight

  • Evaluar cuál sería la visualización adecuada para representar las estadísticas resumidas de las características de height y weight en función de las medallas, separadas además por género de los atletas.

De la visualización estática a la interactiva

Objetivos `

  • Explicar las diferencias entre las visualizaciones estáticas e interactivas

  • Explicar la aplicación de las visualizaciones interactivas en diversos sectores

  • Crear gráficos interactivos con funcionalidades de zoom, hover y slide

  • Utilizar las librerías Bokeh y Plotly (Express) de Python para crear visualizaciones de datos interactivas

En este capítulo, pasaremos de las visualizaciones estáticas a las interactivas y estudiaremos las aplicaciones de las visualizaciones interactivas para diferentes escenarios.

Introducción

  • En la sección anterior hablamos de las visualizaciones de datos estáticas, es decir, gráficos y diagramas que están inmóviles y no pueden ser modificados o interactuados en tiempo real por el público.

  • Las visualizaciones de datos interactivas están un paso por delante de las estáticas. La definición de interactivo es algo que implica la comunicación entre dos o más cosas o personas que trabajan juntas. Por lo tanto, las visualizaciones interactivas son representaciones gráficas de datos analizados (estáticos o dinámicos) que pueden reaccionar y responder a las acciones del usuario en el momento.

Visualización estática versus interactiva

  • Aunque las visualizaciones estáticas de datos son un gran avance hacia el objetivo de extraer y explicar el valor y la información que contienen los conjuntos de datos, la adición de interactividad hace que estas visualizaciones vayan un paso más allá.

Las visualizaciones de datos interactivas tienen las siguientes cualidades:

  • Son más fáciles de explorar ya que permiten interactuar con los datos cambiando colores, parámetros y gráficos.

  • Se pueden manipular fácilmente y al instante. Ya que se puede interactuar con ellas, los gráficos se pueden cambiar delante del usuario. Por ejemplo, usando un deslizador interactivo. Cuando la posición de este deslizador cambia el gráfico también lo hace, además se úeden crear casillas de verificación que le permitan seleccionar los parámetros que desea ver.

  • Permiten acceder a los datos en tiempo real y a la información que proporcionan. Esto permite el análisis eficaz y rápido de las tendencias.

  • Son más fáciles de comprender, lo que permite a las organizaciones tomar mejores decisiones basadas en datos.

  • Eliminan la necesidad de tener varios gráficos para la misma información. Un solo gráfico interactivo es capaz de transmitir la misma información. Permiten observar relaciones (por ejemplo, causa y efecto).

Ejemplo

  • Empecemos con un ejemplo para entender lo que podemos conseguir mediante la visualización interactiva. Consideremos un dataset de socios inscritos en un gimnasio:

  • La siguiente es una visualización de datos estática en forma de gráfico de caja que describe el peso de las personas clasificadas por su sexo (0 es hombre, 1 es mujer y 2 es otro):

  • El único dato que podemos obtener de este gráfico es la relación entre el peso y el sexo. Sin embargo, hay una tercera característica presente en el conjunto de datos que se utiliza para generar este gráfico de caja: la edad. La adición de esta característica al gráfico estático anterior puede llevar a la confusión en cuanto a la comprensión de los datos.

  • Por lo tanto, estamos un poco atascados con respecto a mostrar la relación entre las tres características utilizando una visualización estática. Este problema de problema puede resolverse fácilmente creando una visualización interactiva, como se muestra aquí:

  • En el gráfico de caja anterior, se ha introducido un control deslizante para la característica de la edad. El usuario puede deslizar manualmente la posición del deslizador para observar la relación entre peso, el sexo y la edad en diferentes valores de edad. Además, hay una herramienta de desplazamiento que permite al usuario obtener más información sobre los datos.

  • El gráfico de caja anterior describe que, en este gimnasio, los únicos clientes de 46 años son los que se identifican como otros, y el más pesado de 46 años pesa 82 kilogramos, mientras que el más ligero pesa 56 kilogramos. El usuario puede deslizarse a otra posición para observar la relación entre peso y sexo a una edad diferente, como se muestra en el siguiente gráfico:

  • El gráfico anterior describe los datos a la edad de 34 años: no hay clientes masculinos del gimnasio; Sin embargo, la clienta más pesada de 34 años pesa 100 kilogramos, mientras que la más ligera pesa 71 kilogramos. más ligera pesa 71 kilogramos.

  • Pero aún hay más aspectos a tener en cuenta a la hora de diferenciar entre visualizaciones estáticas e interactivas. Veamos la siguiente tabla:

Visualización Estática

Visualización Interactiva

Medios/campos objetivo

Medios impresos y presentaciones

Aplicaciones web, social media, BI

Coste de creación

Bajo

Alto

Conexión a fuente de datos

No requerida

Requerida en caso dinamico

Visualización

Renderización facil

Requiere diseño de UI

Librerias de Python

Matplotlib, Seaborn

Bokeh, Plotly

  • En última instancia, las visualizaciones de datos interactivas transforman el debate sobre los datos en el arte de contar historias, simplificando así el proceso de comprensión de lo que los datos intentan decirnos. Estos aspectos son los que separan las visualizaciones interactivas de las estáticas. Veamos algunas aplicaciones de las visualizaciones de datos interactivas.

Aplicaciones de las visualizaciones interactivas de datos

  • El aspecto clave de las visualizaciones de datos interactivas es su capacidad de responder y reaccionar a las entradas humanas en el momento o en un lapso de tiempo muy corto. En esta sección, veremos algunas entradas humanas, cómo pueden introducirse en las visualizaciones de datos, y el impacto que tienen en la comprensión de los datos

  • Slider: Un deslizador permite al usuario ver los datos correspondientes a un rango de algo. A medida que el usuario cambia la posición del deslizador, el gráfico cambia en tiempo real. Este permite al usuario ver varios gráficos en tiempo real:

  • Hover: Al pasar (hovering) el cursor por encima de un elemento de un gráfico, el usuario puede recibir más información sobre el punto de datos que la que se puede ver simplemente observando el gráfico. Esto es útil cuando la información que se desea transmitir no cabe en el propio gráfico (como valores precisos o descripciones breves). Veamos una herramienta de hover:

  • Zoom: Acercarse y alejarse de un gráfico es una característica que bastantes bibliotecas de visualización de datos interactivos crean por sí mismas. Le permiten centrarse en puntos de un gráfico y verlos más de cerca.

  • Clickable parameters: Hay varios tipos de parámetros clicables, como casillas de verificación y menús desplegables, que permiten al usuario elegir qué aspectos de los datos desea analizar y ver.

  • Hay bibliotecas de Python que se utilizan para crear estas funciones interactivas, que permiten que las visualizaciones tomen la entrada humana. En los capítulos anteriores, vimos dos bibliotecas de Python incorporadas:

    • matplotlib

    • seaborn

  • Ambos son populares en la comunidad de visualización de datos. Con estas, podemos construir una visualización estática (un gráfico de dispersión estático que muestra la relación entre dos variables) como ésta:

  • Mientras que tanto matplotlib como seaborn son excelentes para las visualizaciones de datos estáticos, hay otras bibliotecas disponibles que hacen un buen trabajo de diseño de características interactivas. Dos de las bibliotecas Python de visualización de datos interactivos más populares son

    • bokeh

    • plotly

  • Esto nos ayuda a crear visualizaciones como las siguientes. Utilizaremos tanto bokeh como plotly en los ejercicios de este capítulo para crear visualizaciones de datos interactivas.

Visualización interactiva de datos con Bokeh

  • bokeh es una biblioteca de Python para la visualización interactiva de datos. Los gráficos de Bokeh se se crean apilando capas una encima de otra. El primer paso es crear una figura vacía figura, a la que se añaden elementos en capas. Estos elementos se conocen como glifos, que pueden ser cualquier cosa, desde líneas hasta barras o círculos. A cada glifo se le adjuntan propiedades como el color, el tamaño y las coordenadas.

  • bokeh es muy popular porque las visualizaciones se renderizan utilizando HTML y JavaScript, por lo que se suele elegir cuando se diseñan visualizaciones interactivas basadas en la web. Además, el módulo bokeh.io crea un archivo .html que contiene estático básico, junto con las características interactivas, y no requiere necesariamente un servidor para ejecutarse, lo que hace que la visualización sea muy fácil de desplegar.

  • En este capítulo, los siguientes ejercicios tienen como objetivo crear una visualización de datos interactiva para representar la relación entre las emisiones de dióxido de carbono y el PIB de un país utilizando la biblioteca bokeh de Python.

Ejercicio 22: Preparación de nuestro conjunto de datos

  • En este ejercicio, descargaremos y prepararemos nuestro conjunto de datos utilizando las bibliotecas incorporadas pandas y numpy. Al final de este ejercicio, tendremos un DataFrame sobre el que construiremos nuestras visualizaciones interactivas de datos. Utilizaremos los archivos co2.csv y gapminder.csv. El primero consiste en las emisiones de dióxido de carbono por persona por año y por país, mientras que el segundo consiste en el PIB por año y por país.

  • Los siguientes pasos le ayudarán a preparar los datos:

  • Importar las bibliotecas pandas y numpy:

import pandas as pd
import numpy as np
  • Guarde el archivo co2.csv en un DataFrame llamado co2, y el archivo gapminder.csv en un DataFrame llamado gm:

url_co2 = 'https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/co2.csv'
co2 = pd.read_csv(url_co2)
co2.head()
country 1800 1801 1802 1803 1804 1805 1806 1807 1808 ... 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
0 Afghanistan NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 0.0529 0.0637 0.0854 0.154 0.242 0.294 0.412 0.35 0.316 0.299
1 Albania NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.3800 1.2800 1.3000 1.460 1.480 1.560 1.790 1.68 1.730 1.960
2 Algeria NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 3.2200 2.9900 3.1900 3.160 3.420 3.300 3.290 3.46 3.510 3.720
3 Andorra NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 7.3000 6.7500 6.5200 6.430 6.120 6.120 5.870 5.92 5.900 5.830
4 Angola NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 0.9800 1.1000 1.2000 1.180 1.230 1.240 1.250 1.33 1.250 1.290

5 rows × 216 columns

url_gm = 'https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/gapminder.csv'
gm = pd.read_csv(url_gm)
gm.head()
Country Year fertility life population child_mortality gdp region
0 Afghanistan 1964 7.671 33.639 10474903.0 339.7 1182.0 South Asia
1 Afghanistan 1965 7.671 34.152 10697983.0 334.1 1182.0 South Asia
2 Afghanistan 1966 7.671 34.662 10927724.0 328.7 1168.0 South Asia
3 Afghanistan 1967 7.671 35.170 11163656.0 323.3 1173.0 South Asia
4 Afghanistan 1968 7.671 35.674 11411022.0 318.1 1187.0 South Asia
  • Actualmente tenemos dos DataFrames separados, cada uno de ellos compuesto por datos que necesitamos para crear nuestra visualización de datos interactiva. Para crear la visualización, necesitamos combinar estos dos DataFrames y eliminar las columnas no deseadas.

  • Utilice .drop_duplicates() para eliminar las instancias duplicadas del gm y guárdelo en un nuevo DataFrame llamado df_gm:

df_gm = gm[['Country', 'region']].drop_duplicates()
df_gm.head()
Country region
0 Afghanistan South Asia
50 Albania Europe & Central Asia
100 Algeria Middle East & North Africa
150 Angola Sub-Saharan Africa
200 Antigua and Barbuda America
  • Utilice .merge() para combinar el DataFrame co2 con el DataFrame df_gm. Esta función función merge básicamente realiza una unión interna en los dos DataFrames (lo mismo como el inner join cuando se utiliza en bases de datos). Esta fusión es necesaria para garantizar que tanto el DataFrame co2 como el DataFrame gm estén formados por los mismos países, garantizando así que los valores de las emisiones de CO2 correspondan a sus respectivos países. how ='inner' Devuelve un marco de datos con sólo las filas que tienen características comunes. Una unión interna requiere que cada fila de los dos marcos de datos unidos tenga valores de columna que coincidan. Esto es similar a la intersección de dos conjuntos.

  • Outer Join or Full outer join: Manitene todas las filas de ambos marcos de datos, especifique how='outer'

  • Left Join or Left outer join: Para incluir todas las filas de su marco de datos \(x\) y sólo las de \(y\) que coincidan, especifique how='left'.

  • Right Join or Right outer join: Para incluir todas las filas de su marco de datos \(y\) y sólo las de \(x\) que coincidan, especifique how='right'.

df_w_regions = pd.merge(co2, df_gm, left_on ='country', right_on ='Country', how ='inner')
df_w_regions.head()
country 1800 1801 1802 1803 1804 1805 1806 1807 1808 ... 2007 2008 2009 2010 2011 2012 2013 2014 Country region
0 Afghanistan NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 0.0854 0.154 0.242 0.294 0.412 0.35 0.316 0.299 Afghanistan South Asia
1 Albania NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.3000 1.460 1.480 1.560 1.790 1.68 1.730 1.960 Albania Europe & Central Asia
2 Algeria NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 3.1900 3.160 3.420 3.300 3.290 3.46 3.510 3.720 Algeria Middle East & North Africa
3 Angola NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.2000 1.180 1.230 1.240 1.250 1.33 1.250 1.290 Angola Sub-Saharan Africa
4 Antigua and Barbuda NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 5.1400 5.190 5.450 5.540 5.360 5.42 5.360 5.380 Antigua and Barbuda America

5 rows × 218 columns

  • Elimina una de las columnas de países ya que hay dos:

df_w_regions = df_w_regions.drop('Country', axis='columns')
df_w_regions.head()
country 1800 1801 1802 1803 1804 1805 1806 1807 1808 ... 2006 2007 2008 2009 2010 2011 2012 2013 2014 region
0 Afghanistan NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 0.0637 0.0854 0.154 0.242 0.294 0.412 0.35 0.316 0.299 South Asia
1 Albania NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.2800 1.3000 1.460 1.480 1.560 1.790 1.68 1.730 1.960 Europe & Central Asia
2 Algeria NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 2.9900 3.1900 3.160 3.420 3.300 3.290 3.46 3.510 3.720 Middle East & North Africa
3 Angola NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 1.1000 1.2000 1.180 1.230 1.240 1.250 1.33 1.250 1.290 Sub-Saharan Africa
4 Antigua and Barbuda NaN NaN NaN NaN NaN NaN NaN NaN NaN ... 4.9100 5.1400 5.190 5.450 5.540 5.360 5.42 5.360 5.380 America

5 rows × 217 columns

  • A continuación, vamos a aplicar la función .melt() a este DataFrame y a almacenarlo en un nuevo DataFrame llamado new_co2. Esta función cambia el formato de un DataFrame en uno que tenga variables identificadoras de nuestra elección. En nuestro caso queremos que las variables identificadoras sean país y región, ya que son las constantes. También vamos a cambiar el nombre de las columnas:

new_co2 = pd.melt(df_w_regions, id_vars=['country', 'region'])
new_co2.tail(10)
country region variable value
37185 United Arab Emirates Middle East & North Africa 2014 23.300
37186 United Kingdom Europe & Central Asia 2014 6.460
37187 United States America 2014 16.500
37188 Uruguay America 2014 1.970
37189 Uzbekistan Europe & Central Asia 2014 3.450
37190 Vanuatu East Asia & Pacific 2014 0.595
37191 Venezuela America 2014 6.030
37192 Vietnam East Asia & Pacific 2014 1.800
37193 Zambia Sub-Saharan Africa 2014 0.288
37194 Zimbabwe Sub-Saharan Africa 2014 0.780
columns = ['country', 'region', 'year', 'co2']
new_co2.columns = columns
new_co2.tail(10)
country region year co2
37185 United Arab Emirates Middle East & North Africa 2014 23.300
37186 United Kingdom Europe & Central Asia 2014 6.460
37187 United States America 2014 16.500
37188 Uruguay America 2014 1.970
37189 Uzbekistan Europe & Central Asia 2014 3.450
37190 Vanuatu East Asia & Pacific 2014 0.595
37191 Venezuela America 2014 6.030
37192 Vietnam East Asia & Pacific 2014 1.800
37193 Zambia Sub-Saharan Africa 2014 0.288
37194 Zimbabwe Sub-Saharan Africa 2014 0.780
  • Establezca el límite inferior de la columna del año como 1964 para que la columna consista en valores int64 para 1964 y en adelante. Haga esto dentro del DataFrame new_co2 que creamos en el paso anterior, y almacénelo en un nuevo DataFrame llamado df_co2. Ordene los valores del DataFrame df_co2 por la columna del país y luego haga lo mismo con la columna del año utilizando .sort_values().

df_co2 = new_co2[new_co2['year'].astype('int64') > 1963]
df_co2 = df_co2.sort_values(by=['country', 'year'])
df_co2['year'] = df_co2['year'].astype('int64')
df_co2.head()
country region year co2
28372 Afghanistan South Asia 1964 0.0863
28545 Afghanistan South Asia 1965 0.1010
28718 Afghanistan South Asia 1966 0.1080
28891 Afghanistan South Asia 1967 0.1240
29064 Afghanistan South Asia 1968 0.1160
  • Ahora tenemos un DataFrame que consiste en las emisiones de dióxido de carbono por año y por país. Los números de serie no están en orden ascendente porque hemos ordenado los datos por la columna del país y luego por la del año. A continuación, vamos a crear una tabla similar para el PIB por año y por país.

  • Cree un nuevo DataFrame llamado df_gdp que conste de las columnas country, year y gdp del DataFrame gm

df_gdp = gm[['Country', 'Year', 'gdp']]
df_gdp.columns = ['country', 'year', 'gdp']
df_gdp.head()
country year gdp
0 Afghanistan 1964 1182.0
1 Afghanistan 1965 1182.0
2 Afghanistan 1966 1168.0
3 Afghanistan 1967 1173.0
4 Afghanistan 1968 1187.0
  • Finalmente tenemos dos DataFrames que consisten en lo siguiente: Las emisiones de dióxido de carbono y el PIB. Combine los dos DataFrames utilizando la función .merge() en las columnas país y año. Guarde esto en un nuevo DataFrame llamado data. Utilice la función dropna() para eliminar los valores NaN

data = pd.merge(df_co2, df_gdp, on=['country', 'year'], how='left')
data = data.dropna()
data.head()
country region year co2 gdp
0 Afghanistan South Asia 1964 0.0863 1182.0
1 Afghanistan South Asia 1965 0.1010 1182.0
2 Afghanistan South Asia 1966 0.1080 1168.0
3 Afghanistan South Asia 1967 0.1240 1173.0
4 Afghanistan South Asia 1968 0.1160 1187.0
  • Por último, comprobemos la correlación entre las emisiones de dióxido de carbono y el PIB para asegurarnos de que estamos analizando datos que merecen ser visualizados. Crea un array numpy con las columnas co2 y gdp:

np_co2 = np.array(data['co2'])
np_gdp = np.array(data['gdp'])
  • Utilice la función .corrcoef() para imprimir la correlación entre las emisiones de y el PIB:

np.corrcoef(np_co2, np_gdp)
array([[1.        , 0.78219731],
       [0.78219731, 1.        ]])
  • Como se puede ver en el resultado anterior, hay una alta correlación entre las emisiones de dióxido de carbono y el PIB.

Ejercicio 23: Creación del gráfico estático base para una visualización de datos interactiva

  • En este ejercicio, vamos a crear un gráfico estático para nuestro conjunto de datos y a añadirle glifos circulares circulares. Los siguientes pasos te ayudarán con la solución:

  • Import the following:

    • curdoc de bokeh.io: Esto devuelve el estado actual por defecto del documento/ gráfico.

    • La figura de bokeh.plotting: Esto crea la figura para el trazado.

    • HoverTool, ColumnDataSource, CategoricalColorMapper y Slider de bokeh.models: Son herramientas y métodos interactivos para mapear datos de pandas DataFrames a una fuente de datos para su trazado.

    • Spectral6 de bokeh.palettes: Una paleta de colores para la gráfica.

    • widgetbox y row de bokeh.layouts: widgetbox crea una columna de herramientas predefinidas (incluyendo el zoom), mientras que row crea una fila de objetos de diseño bokeh, lo que les obliga a tener el mismo sizing_mode:

from bokeh.io import curdoc, output_notebook
from bokeh.models import HoverTool, ColumnDataSource, CategoricalColorMapper, Slider, CustomJS
from bokeh.palettes import Spectral6
from bokeh.layouts import widgetbox, row
from ipywidgets import interact
from bokeh.io import push_notebook, show, output_notebook
from bokeh.layouts import column
from bokeh.plotting import Figure, output_file, show
  • Ejecute la función output_notebook() para cargar BokehJS. Esto es lo que permite que el que se muestre en el notebook:

output_notebook()
Loading BokehJS ...
  • Vamos a codificar por colores nuestros puntos de datos (que serán los países individuales) en función de la región a la que pertenecen. Para ello, cree una lista de regiones aplicando la función .unique() a la columna región del DataFrame. Haga que una lista utilizando el método .tolist():

regions_list = data.region.unique().tolist()
  • Utilice CategoricalColorMapper para asignar un color del paquete Spectral6 a las diferentes regiones presentes en la lista regions_list:

color_mapper = CategoricalColorMapper(factors=regions_list, palette=Spectral6)
  • Utilizando la función ColumnDataSource construimos un diccionaro con las variables utlizadas en la grafica el cual llamaremos source_init. También crearemos otro que utlizaremos para actualizar la figura no estática por año la cual llamamos source_last

source_init = ColumnDataSource(data={'x': data.gdp[data.year == min(data.year)],
                                     'y': data.co2[data.year == min(data.year)],
                                     'country': data.country[data.year == min(data.year)],
                                     'region': data.region[data.year == min(data.year)],
                                     'year': data.year[data.year == min(data.year)]})
source_last = ColumnDataSource(data={'x': data.gdp, 'y': data.co2, 'year': data.year})
  • Creamos la figura vacía:

    • Establece el título como Emisiones de CO2 versus PIB en 1964

    • Establece el rango del eje x de xmin a xmax

    • Establece el rango del eje y desde ymin hasta ymax

    • Establezca el tipo de eje y como logarítmico

plot = Figure(title='CO2 Emissions vs GDP in 1964', y_axis_type='log')
  • Añadimos glifos circulares a la gráfica:

plot.circle(x='x', y='y', 
            fill_alpha=0.8, 
            source=source_init, 
            legend_label='region', 
            color=dict(field='region', transform=color_mapper),
            size=7)
GlyphRenderer(
id = '1043', …)
  • Establezca la ubicación de la leyenda en la esquina inferior derecha del gráfico, y agregue títulos a los ejes

plot.legend.location = 'bottom_right'
plot.xaxis.axis_label = 'Income Per Person'
plot.yaxis.axis_label = 'CO2 Emissions (tons per person)'

Ejercicio 24: Añadir una herramienta Hover

  • En este ejercicio, vamos a permitir que el usuario pase por encima de un punto de datos en nuestro gráfico para ver el nombre del país, las emisiones de dióxido de carbono y el PIB. Los siguientes pasos te ayudarán con la solución:

  • Crear una herramienta de rastreo llamada hover. Añade la herramienta hover a la gráfica

hover = HoverTool(tooltips=[('Country', '@country'), ('GDP', '@x'), ('CO2 Emission', '@y')])
plot.add_tools(hover)
show(plot)

Ejercicio 24: Añadir un deslizador al gráfico estático

  • Nombramos el archivo HTML de salida como co2_emissions

output_file("co2_emissions.html")
  • Creamos la función callback usando CustomJS de la libreria bokeh la cual permitira actualizar nuestra figura. Usamos algunas pocas ordenes en lenguaje JavaScript.

callback = CustomJS(args=dict(source_last=source_last, source_init=source_init), code="""
    var data_init = source_init.data;
    var yr = cb_obj.value;
    var year = source_last.data['year'];
    var x_new = [];
    var y_new = [];
    for(var i = 0; i < year.length; i++) {
        if(year[i] == yr) {
            x_new.push(source_last.data['x'][i]);
            y_new.push(source_last.data['y'][i]);
        }
    }
    data_init['x'] = x_new;
    data_init['y'] = y_new;
    source_init.change.emit();
    """)
  • Construimos el slider que utlizaremos para actualizar las figuras, y realizamos el llamado de la función callback que recibirá como input cada año que proviende del slider

slider = Slider(start=min(data.year), end=max(data.year), step=1, value=min(data.year), title='Year')
slider.js_on_change('value', callback)

layout = column(slider, plot)
show(layout)
  • Como puede ver, en la esquina derecha, hay varias herramientas. Estas son generadas automáticamente por Bokeh cuando se crea un gráfico

Estas herramientas son las siguientes:

  • Pan: La herramienta de desplazamiento le permite mover y cambiar la vista de su parcela

  • Box Zoom: Le permite ampliar una sección cuadrada concreta de la cuadrado de la parcela

  • Wheel Zoom: Le permite acercarse arbitrariamente a cualquier punto del gráfico.

  • Save Plot: Permite guardar el gráfico actual.

  • Reset: Esto restablece el gráfico y le lleva de vuelta al gráfico original en el que aterrizó. a la parcela original.

  • Hover: Creamos una herramienta de hover en nuestra parcela y la programamos para que muestre cierta información. Sin embargo, Bokeh también genera automáticamente una herramienta hover que puede ser activada y desactivada por este icono. Esta herramienta puede no mostrar siempre lo que que queremos, por lo que hemos creado una nosotros mismos.

Visualización interactiva de datos con Plotly Express

  • Plotly es una biblioteca de Python muy popular y se utiliza para crear sorprendentes e informativas visualizaciones de datos interactivos.

  • Es una herramienta de ploteo basada en JSON, por lo que cada ploteo está definido por dos objetos JSON - datos y diseño.

  • El despliegue de una visualización Plotly requiere un poco más de esfuerzo que una visualización Bokeh porque tenemos que construir una aplicación separada (más comúnmente una aplicación Flask) utilizando el marco Dash.

  • En comparación con Bokeh, las herramientas y la sintaxis de Plotly son mucho más sencillas. Sin embargo, el código que se requiere para crear estas visualizaciones de datos interactivos es un poco más extenso.

Ejercicio 26: Creación de un gráfico de dispersión interactivo

  • En este ejercicio, vamos a crear una visualización de datos interactiva del DataFrame que creamos en el ejercicio anterior, de las emisiones de dióxido de carbono y el PIB. Los siguientes pasos te ayudarán con la solución

  • Abra un nuevo cuaderno Jupyter. Importe las siguientes bibliotecas y paquetes:

    • pandas: Para preparar el DataFrame

    • plotly.express: Para crear las gráficas

import pandas as pd
import plotly.express as px
  • Cree el DataFrame de emisiones de dióxido de carbono y PIB del ejercicio anterior en este notebook:

url_co2 = 'https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/co2.csv'
co2 = pd.read_csv(url_co2)
url_gm = 'https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/gapminder.csv'
gm = pd.read_csv(url_gm)

df_gm = gm[['Country', 'region']].drop_duplicates()
df_w_regions = pd.merge(co2, df_gm, left_on='country', right_on='Country', how='inner')
df_w_regions = df_w_regions.drop('Country', axis='columns')
new_co2 = pd.melt(df_w_regions, id_vars=['country', 'region'])
columns = ['country', 'region', 'year', 'co2']
new_co2.columns = columns

df_co2 = new_co2[new_co2['year'].astype('int64') > 1963]
df_co2 = df_co2.sort_values(by=['country', 'year'])
df_co2['year'] = df_co2['year'].astype('int64')
df_gdp = gm[['Country', 'Year', 'gdp']]
df_gdp.columns = ['country', 'year', 'gdp']
data = pd.merge(df_co2, df_gdp, on=['country', 'year'], how='left')
data = data.dropna()

data.head()
country region year co2 gdp
0 Afghanistan South Asia 1964 0.0863 1182.0
1 Afghanistan South Asia 1965 0.1010 1182.0
2 Afghanistan South Asia 1966 0.1080 1168.0
3 Afghanistan South Asia 1967 0.1240 1173.0
4 Afghanistan South Asia 1968 0.1160 1187.0
  • Guarda los valores mínimo y máximo del PIB como xmin y xmax respectivamente

xmin, xmax = min(data.gdp), max(data.gdp)
  • Repita el paso 4 para los valores mínimos y máximos de emisión de dióxido de carbono

ymin, ymax = min(data.co2), max(data.co2)
  • Crea el gráfico de dispersión y guárdalo como fig:

    • El parámetro data será el nombre de nuestro DataFrame, es decir, data.

    • Asigna la columna gdp al eje x.

    • Asigna la columna co2 al eje y.

    • Establecer el parámetro animation_frame como la columna del año.

    • Establezca el parámetro animation_group como la columna del país.

    • Establezca el color de los puntos de datos como la columna región.

    • Asigna la columna country al parámetro hover_name.

    • Establecer el parámetro facet_col como la columna región (esto divide nuestro gráfico en seis columnas, una para cada región).

    • Establece la anchura como 1579 y la altura como 400.

    • El eje x debe ser logarítmico.

    • Establezca el parámetro size_max como 45.

    • Asigna el rango del eje x y del eje y como xmin, xmax y ymin, ymax, respectivamente

fig = px.scatter(data, 
                 x="gdp", y="co2", 
                 animation_frame="year",
                 animation_group="country", 
                 color="region", 
                 hover_name="country",
                 facet_col="region", 
                 width=1579, height=400, 
                 log_x=True, 
                 size_max=45,
                 range_x=[xmin,xmax],
                 range_y=[ymin,ymax])
fig.show()

Observaciones

  • Como puede ver, tenemos un gráfico con seis subplots; uno para cada región.

  • Cada región está codificada por colores.

  • Cada subgrupo tiene las emisiones de dióxido de carbono en toneladas por persona como eje y la renta por persona en el eje de abscisas.

  • En la parte inferior del gráfico hay un control deslizante que nos permite comparar la correlación entre las emisiones de dióxido de carbono y la renta por año entre regiones y países por año.

  • Al pulsar el botón de reproducción en la esquina inferior izquierda, el gráfico progresa automáticamente desde el año 1964 hasta el 2013, mostrándonos cómo los puntos de datos con el tiempo.

  • También podemos mover manualmente el deslizador

  • Además, podemos pasar el ratón por encima de un punto de datos para obtener más información sobre él

  • Como puede ver, la creación de una visualización de datos interactivos con Plotly Express toma muy pocas líneas de código y la sintaxis es fácil de aprender y utilizar. Además de los gráficos de dispersión, la biblioteca biblioteca tiene muchos otros tipos de gráficos que puede utilizar para visualizar interactivamente diferentes tipos de datos los cuales serán estudiandos en las siguientes actividades.

  • Haga clic en el siguiente enlace para consultar otras gráficas disponibles con: Plotly Express

Tarea 1.3

  • En esta actividad, trabajará con el mismo conjunto de datos que trabajó en los ejercicios de este capítulo. Es importante que pruebes varios tipos de visualización para para determinar la visualización que mejor transmite el mensaje que está tratando de dar con sus datos. Vamos a crear algunas visualizaciones interactivas utilizando la biblioteca Plotly Express para determinar cuál es la que mejor se adapta a nuestros datos.

    1. Vuelve a crear el DataFrame de las emisiones de dióxido de carbono y del PIB.

    2. Crea un gráfico de dispersión con los ejes x e y como year y co2 respectivamente. Añada un para los valores de co2 con el parámetro marginaly_y.

    3. Crea un gráfico de caja para los valores del PIB con el parámetro marginal_x. Añada los parámetros de parámetros de animación en la columna del año

    4. Crea un gráfico de dispersión con los ejes x e y como gdp y co2 respectivamente.

    5. Cree un contorno de densidad con los ejes x e y como pib y co2 respectivamente.

Resumen

  • En este capítulo, hemos aprendido que las visualizaciones de datos interactivas están un paso por delante de las de las visualizaciones de datos estáticas debido a su capacidad para responder a las entradas humanas en tiempo real.

  • La gama de aplicaciones de las visualizaciones de datos interactivas es muy amplia, y podemos visualizar casi cualquier tipo de datos de forma interactiva.

  • Las entradas humanas que pueden incorporarse a las visualizaciones de datos interactivas incluyen, pero no se limitan a los controles deslizantes, las funciones de zoom, las herramientas de desplazamiento y los parámetros en los que se puede hacer clic.

  • Bokeh y Plotly Express son dos de las bibliotecas de Python más populares y sencillas para crear visualizaciones de datos interactivas.

  • En la proxima sección, veremos cómo crear hermosas visualizaciones de datos interactivas basadas en el contexto.

Visualización de datos a través de estratos

Objetivos

  • Crear interactividad en los gráficos de dispersión utilizando altair

  • Utilizar el zoom in y out, hover y tooltip, y seleccionar y resaltar en los gráficos de dispersión

  • Crear gráficos de barras y mapas de calor interactivos

  • Crear enlaces dinámicos entre diferentes tipos de gráficos dentro de una única visualización interactiva

En este capítulo, aprenderá a crear visualizaciones interactivas para datos estratificados con respecto a cualquier variable categórica.

Introducción

  • Una observación hecha en la sección anterior fue que cuando cuando se trata de introducir interactividad en ciertos tipos de gráficos de Python, plotly puede a veces ser verboso, y puede implicar una curva de aprendizaje empinada. Por lo tanto, en este capítulo, presentaremos altair, una biblioteca diseñada especialmente para generar gráficos interactivos. - Demostraremos cómo crear visualizaciones interactivas con altair para datos estratificados con respecto a cualquier variable categórica. A modo de ilustración, utilizaremos un conjunto de datos para generar gráficos de dispersión y de barras con las características del conjunto de datos y añadir una variedad de elementos interactivos a los gráficos. También conoceremos algunas ventajas específicas del uso de altair sobre una biblioteca más polivalente como plotly.

  • Utilizaremos el conjunto de datos del Índice de Felicidad Planetaria (IPH) http://happyplanetindex.org/ a lo largo de esta sección. Este conjunto de datos muestra en qué lugares del mundo la gente utiliza recursos ecológicos de forma más eficiente para vivir una vida larga y feliz. No sólo es un recurso interesante para conocer mejor las condiciones ecológicas y el bienestar socioeconómico de bienestar socioeconómico en varias partes de nuestro planeta, sino que también tiene una interesante mezcla de características que nos ayudan a demostrar ciertos conceptos clave de la visualización interactiva.

Gráficos de dispersión interactivos

  • Como ya sabe, los gráficos de dispersión son uno de los tipos de gráficos más esenciales para presentar patrones globales dentro de un conjunto de datos. Naturalmente, es importante saber cómo introducir la interactividad en estos gráficos. En primer lugar, veremos las acciones de zoom y restablecimiento de los gráficos. Antes de eso, sin embargo, vamos a echar un vistazo al conjunto de datos. Podemos ver el conjunto de datos del IPH utilizando el siguiente código

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
hpi_df.head()
HPI Rank Country Region Life Expectancy (years) Wellbeing (0-10) Inequality of outcomes Ecological Footprint (gha/capita) Happy Planet Index
0 1 Costa Rica Americas 79.1 7.3 15% 2.8 44.7
1 2 Mexico Americas 76.4 7.3 19% 2.9 40.7
2 3 Colombia Americas 73.7 6.4 24% 1.9 40.7
3 4 Vanuatu Asia Pacific 71.3 6.5 22% 1.9 40.6
4 5 Vietnam Asia Pacific 75.5 5.5 19% 1.7 40.3
  • Tenga en cuenta que hay 5 características numéricas/cuantitativas en este conjunto de datos:

    • Life Expectancy (years)

    • Wellbeing (0-10)

    • Inequality of outcomes

    • Ecological Footprint (gha/capita)

    • Happy Planet Index

  • Hay dos características categóricas/nominales: Country y Region. En altair los rasgos cuantitativos se denotan como Q, y los rasgos nominales se denotan como N. Veremos pronto cómo utilizar esto en nuestras visualizaciones.

  • Generemos y observemos un gráfico de dispersión estático, mediante un ejercicio, de las caracteristicas Wellbeing (0-10) and Happy Planet Index para cada país, utilizando diferentes colores para denotar la región a la que pertenece el país y seguir adelante y añadirle interactividad.

Ejercicio 27: Añadir Zoom-In y Zoom-Out a un gráfico de dispersión estático

  • En este ejercicio, generaremos un gráfico de dispersión estático utilizando matplotlib. Utilizaremos el conjunto de datos hpi_data_countries para el gráfico y analizaremos las puntuaciones de Wellbeing de cada país representado por la leyenda del gráfico. Seguiremos adelante y añadiremos una función de zoom. Para ello utilizaremos la biblioteca altair.

  • Cargar el conjunto de datos hpi y leer desde el conjunto de datos usando pandas:

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Trazar un gráfico de dispersión estático utilizando matplotlib

import seaborn as sns
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax = sns.scatterplot(x='Wellbeing (0-10)', y='Happy Planet Index', hue='Region', data=hpi_df)
plt.show()
_images/.~notebooks_458_0.png
  • Cada punto representa un país de una de las 7 regiones. El Wellbeing y el Happy Planet Index parecen estar correlacionados. Vemos una tendencia en las puntuaciones del Happy Planet Index y las puntuaciones de Wellbeing de las distintas regiones. Ahora que tenemos un gráfico de dispersión estático, vamos a explorar la interactividad de este gráfico. Veremos cómo hacer zoom in y zoom out.

  • Importa el módulo altair como alt. Antes debe instalar altair usando pip install altair vega_datasets. En versiones anteriores de notebook (<5.3) es necesario habilitar adicionalmente la extensión: jupyter nbextension install --sys-prefix --py vega

import altair as alt
  • Proporcione el DataFrame elegido (hpi_df en nuestro caso) a la función altair Chart. Utilice la función mark_circle() para denotar puntos de datos en el gráfico de dispersión utilizando círculos rellenos.

  • Utilice la función encode para especificar las características en los ejes \(x\) e \(y\). Aunque también usamos el parámetro de color en esta función para color-code los puntos de datos usando la característica de la región, esto es opcional. Por último, añada la función interactive() para que el gráfico sea interactivo para zooming

alt.Chart(hpi_df).mark_circle().encode(
    x='Wellbeing (0-10):Q',
    y='Happy Planet Index:Q',
    color='Region:N',).interactive()
  • ¿Se ha dado cuenta de que hemos añadido un sufijo: Q junto a nuestras características cuantitativas y un sufijo: N junto a nuestras características nominales? Añadir sufijos como éste ayuda a altair a conocer el tipo de antemano, en lugar de tener que inferirlo por sí mismo.

  • Puede intentar eliminar los sufijos en este gráfico y verá que el gráfico se sigue generando sin errores porque altair puede adivinar el tipo de característica en este caso. Es una buena práctica incluir los sufijos ya que hay casos en los que altair no puede inferir el tipo de característica.

  • Los diversos parámetros, como \(x\), y \(y\) el color, que especificamos en la función de codificación son llamados canales en altair.

Ejercicio 28: Añadir la funcionalidad Hover y Tooltip a un gráfico de dispersión

  • Cargar el conjunto de datos hpi y leer desde el conjunto de datos usando pandas:

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Importa el módulo altair como alt

import altair as alt
  • Proporcione el DataFrame elegido (hpi_df en nuestro caso) a la función altair Chart de altair. Utilice la función mark_circle() para indicar los puntos de datos en el gráfico de dispersión de dispersión mediante círculos rellenos. Utilice la función encode para especificar las características en los ejes \(x\) y \(y\). Aunque utilizamos el parámetro de color en esta función para codificar en color los puntos de datos utilizando la característica de región, esto es opcional.

alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = 'Region:N',
    tooltip = ['Country', 'Region', 'Wellbeing (0-10)', 'Happy Planet Index', 'Life Expectancy (years)']
)
  • En el gráfico anterior, verá que las características mencionadas en el parámetro “tooltip” de la función de codificación se muestran cuando el cuando el cursor se acerca a cualquier punto de datos. Sin embargo, la función de zoom se ha perdido. ¿Cómo puede recuperarla? Muy sencillo: ¡añada la función interactive()!

  • Añade la función interactive() para recuperar la función de zoom en el gráfico como como se muestra aquí

alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = 'Region:N',
    tooltip = ['Country', 'Region', 'Wellbeing (0-10)', 'Happy Planet Index', 'Life Expectancy (years)']
).interactive()
  • Consideremos ahora un escenario más interesante. Supongamos que queremos seleccionar un área en el gráfico para examinar los puntos de datos dentro de ella

Ejercicio 29: Explorar la funcionalidad de seleccionar y resaltar en un gráfico de dispersión

  • En este ejercicio, vamos a utilizar la funcionalidad de seleccionar y resaltar utilizando altair. Nosotros podemos hacer esto usando una función llamada add_selection. Primero tenemos que definir una variable que almacenará un intervalo de selección y luego generar el gráfico al que queremos añadir la función de selección. En el gráfico resultante, podemos hacer clic y luego arrastrar el cursor para crear un área de selección, que se coloreará de gris. Sigamos los siguientes pasos para hacerlo

  • Cargar el conjunto de datos hpi y leer desde el conjunto de datos usando pandas:

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Importa el módulo altair como alt

import altair as alt
  • Defina la variable selected_area para almacenar el intervalo de selección

selected_area = alt.selection_interval()
  • Proporcione el DataFrame elegido (hpi_df en nuestro caso) a la función altair Chart de altair

  • Utilice la función mark_circle() para denotar puntos de datos en el gráfico de dispersión utilizando círculos rellenos. Utilice la función encode para especificar las características en los ejes \(x\) e y \(y\). Aunque hemos utilizado el parámetro de color en esta función para colorear los puntos de datos utilizando la característica de región, esto es opcional. Utilice la función add_selection() para especificar el área seleccionada

alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = 'Region:N'
).add_selection(
    selected_area
)
  • Añade alt_value como lightgray para que todos los puntos fuera de la selección sean grises

selected_area = alt.selection_interval()
alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = alt.condition(selected_area, 'Region:N', alt.value('lightgray'))
).add_selection(
    selected_area
)
  • Establecemos el parámetro de color en la función de codificación a una condición de altair que retiene los colores de sólo los puntos dentro del área seleccionada. Esto puede ser útil cuando se desea obtener información sobre un rango particular de características en los ejes de un gráfico de dispersión.

Ejercicio 30: Generación de un trazado con las funciones de selección, zoom y hover/hoja de cálculo

  • En este ejercicio, seguiremos trabajando con el conjunto de datos del Happy Planet Index. La tarea de tarea consiste en crear un gráfico de dispersión para Well-being vs Happy Planet Index y hacer zoom en el área con un alto Well-being y un alto Happy Planet index. Tendrá que determinar qué región predomina en el área de selección y, a continuación, enumerar los países de la zona. Sigamos los siguientes pasos:

  • Cargar el conjunto de datos hpi y leer desde el conjunto de datos usando pandas:

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Importa el módulo altair como alt

import altair as alt
  • Cree un gráfico de dispersión de altair para Wellbeing vs Happy Planet Index junto con la función de zoom, utilizando la función interactive(), y haz un zoom en el área que incluye el conjunto de puntos de datos en la parte superior derecha

alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = 'Region:N'
).interactive()
  • Ahora añada la característica de selección cambiando el parámetro de color para incluir la condición de selección de altair

selected_area = alt.selection_interval()
alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = alt.condition(selected_area, 'Region:N', alt.value('lightgray'))
).interactive().add_selection(
    selected_area
)
  • Obsérvese que la mayoría de los países de la zona de selección (arriba a la derecha) pertenecen a América (de color azul). ¿Esperabas esto basándote en tus conocimientos generales? Añadamos la función para saber qué países aparecen en nuestra área de interés.

  • Añade la función tooltip para localizar el área de interés

selected_area = alt.selection_interval()
alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color=alt.condition(selected_area, 'Region:N', alt.value('lightgray')),
    tooltip= ['Country', 'Region', 'Wellbeing (0-10)', 
              'Happy Planet Index', 'Life Expectancy (years)']
).interactive().add_selection(
    selected_area
)
  • Si pasa el ratón por encima de la zona de interés, verá que los principales países son Costa Rica, México, Panamá y Colombia. Ahora, pasemos a la siguiente sección para observar cómo se puede utilizar la función de selección a través de múltiples figuras.

Ejercicio 31: Selección a través de múltiples parcelas

  • La función de selección puede ser mucho más potente cuando se vincula a varios gráficos. Consideraremos el ejemplo de dos gráficos de dispersión:

    • wellbeing vs happy planet index

    • life expectancy vs happy planet index

  • En este ejercicio, vamos a ir paso a paso para generar un gráfico interactivo. Para nuestro primer gráfico de dispersión, ya que queremos que el eje y sea común en ambos gráficos, especificaremos sólo el eje \(y\) en la función de codificación de nuestro gráfico de altair, y luego añadiremos las características del eje \(x\) por separado en el objeto Chart. Además, para poner los dos gráficos uno detrás de otro y permitir la selección entre ellos, utilizaremos la función altair vconcat

  • Cargar el conjunto de datos hpi y leer desde el conjunto de datos usando pandas:

import pandas as pd

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Importa el módulo altair como alt

import altair as alt
  • Trace el gráfico de dispersión con la función Chart altair vconcat para colocar dos gráficos verticalmente uno tras otro

chart = alt.Chart(hpi_df).mark_circle().encode(
    y='Happy Planet Index',
    color='Region:N'
)
chart1 = chart.encode(x = 'Wellbeing (0-10)')
chart2 = chart.encode(x = 'Life Expectancy (years)')
alt.vconcat(chart1, chart2)
  • Por cierto, existen atajos para las funciones hconcat y vconcat. Podemos sustituir alt.hconcat(chart1, chart2) por chart1 | chart2 y alt.vconcat(chart1, chart2) por chart1 & chart2

  • Añade las funciones hover y tooltip que enlazan los dos gráficos utilizando el siguiente código

# hover and tooltip across multiple charts
selected_area = alt.selection_interval()
chart = alt.Chart(hpi_df).mark_circle().encode(
    y = 'Happy Planet Index',
    color=alt.condition(selected_area, 'Region', alt.value('lightgray'))
).add_selection(
    selected_area
)
chart1 = chart.encode(x = 'Wellbeing (0-10)')
chart2 = chart.encode(x = 'Life Expectancy (years)')
chart1 | chart2
  • Intente seleccionar un área en cualquiera de las gráficas. Observará que la selección en un gráfico automáticamente lleva a resaltar los mismos puntos de datos en el otro gráfico.

Ejercicio 32: Selección basada en los valores de una característica

  • En este ejercicio, crearemos un gráfico interactivo donde podremos ver los puntos de datos en función de una Region determinada. Utilizaremos la función selection_single() para obtener un conjunto seleccionado de puntos de datos. Si se estudia el código con atención, se verá que los parámetros de esta función se explican por sí mismos. Para cualquier aclaración, por favor lea sobre ellos en la documentación oficial en https://altair-viz.github.io/user_guide/generated/api/altair.selection_single.html.

  • Importe los módulos de Python necesarios

import altair as alt
import pandas as pd
  • Lectura del conjunto de datos:

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Cree una variable input_dropdown utilizando la función binding_select() y establezca el parámetro options en la lista de regiones de nuestro conjunto de datos. Utilice la función selection_single() para seleccionar un conjunto de puntos de datos. Utilice la variable de color para almacenar la condición bajo la cual se seleccionarán los puntos de dato

input_dropdown = alt.binding_select(options = list(set(hpi_df.Region)))
selected_points = alt.selection_single(fields = ['Region'], bind = input_dropdown, name = 'Select')
color = alt.condition(selected_points,
                      alt.Color('Region:N'),
                      alt.value('lightgray'))
alt.Chart(hpi_df).mark_circle().encode(
    x = 'Wellbeing (0-10):Q',
    y = 'Happy Planet Index:Q',
    color = color,
    tooltip='Region:N'
).add_selection(
    selected_points
)
  • El gráfico anterior tiene inicialmente todos sus puntos de datos en color. Sin embargo, al seleccionar un valor para la característica Region en el menú desplegable de entrada, observará que los correspondientes países están resaltados en color, mientras que todos los demás países están en gris. En los dos gráficos anteriores, el primero muestra los puntos de datos de la región de Americas y el segundo gráfico muestra los puntos de datos de la región Post-communist.

  • Ahora que sabemos cómo añadir interactividad a los gráficos de dispersión, vamos a aprender a introducir la interactividad en otros dos tipos de visualización importantes: los gráficos de barras y los mapas de calor

Ejercicio 33: Añadir una función de Zoom-In/Zoom-Out y calcular la media en un gráfico de barras estático

  • En este ejercicio, primero generaremos un simple gráfico de barras (estático) y luego exploraremos la interactividad, como el acercamiento y el alejamiento. A continuación, utilizaremos el mismo gráfico de barras y averiguaremos la media del Happy Planet Index de cada región. Utilizaremos la biblioteca altair y el conjunto de datos del Happy Planet Index

  • Importe los módulos de Python necesarios

import altair as alt
import pandas as pd
  • Lectura del conjunto de datos:

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Utilice la función mark_bar() para señalar puntos de datos en el gráfico de barras. Utilice la función encode para especificar las características en los ejes \(x\) e \(y\)

mean(hpi_df['Happy Planet Index'])
# hpi_df.head()
26.407857142857146
alt.Chart(hpi_df).mark_bar().encode(
    x='Region:N',
    y='mean(Happy Planet Index):Q',
)
  • Sin embargo, el gráfico anterior parece demasiado estrecho. Podemos arreglar esto fácilmente estableciendo el anchura del gráfico a un valor diferente utilizando la función de propiedades. Establezca el ancho a 400 utilizando la función de propiedades para aumentar el ancho del gráfico de barras:

alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'mean(Happy Planet Index):Q'
).properties(width=400)
  • Utiliza la función interactive para zoom in/out:

import altair as alt

alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = alt.Y('Happy Planet Index')
).properties(width=400).interactive()
  • Utilice el operador | para mostrar la media del IPH en todas las regiones:

import altair as alt

bars = alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'mean(Happy Planet Index):Q'
).properties(width=400)

line = alt.Chart(hpi_df).mark_rule(color='firebrick').encode(
    y = 'mean(Happy Planet Index):Q',
    size = alt.SizeValue(3)
)
bars | line
  • No queremos que la línea se coloque junto a nuestro gráfico de barras. La queremos en el gráfico. Entonces, ¿cómo lo hacemos? Para ello, tenemos que utilizar el concepto de capa en altair. La idea es crear variables para almacenar el gráfico de barras y el gráfico de líneas, y luego superponerlos uno encima del otro.

  • Add the layer function from the altair library

import altair as alt

bars = alt.Chart().mark_bar().encode(
    x = 'Region:N',
    y = 'mean(Happy Planet Index):Q'
).properties(width=400)

line = alt.Chart().mark_rule(color='firebrick').encode(
    y='mean(Happy Planet Index):Q',
    size = alt.SizeValue(3)
)

alt.layer(bars, line, data=hpi_df)
  • Así pues, ahora sabemos que la media del Índice del Planeta Feliz en todas las regiones es de alrededor de 26. Además, también hay que tener en cuenta que no especificamos el conjunto de datos hasta que utilizamos la función de capa. Es decir, no proporcionamos el conjunto de datos hpi_df en la función Chart() como es habitual. En su lugar, lo mencionamos en la función de capa con el parámetro data = hpi_df.

  • Ahora que conoce el concepto de estratificación en altair, puede confiar en un atajo para ello. Sólo tienes que escribir el código de forma independiente para diferentes parcelas, como lo harías normalmente, y luego utilizar el operador +, como se muestra en el siguiente ejemplo

Ejercicio 34: Un atajo alternativo para representar la media en un gráfico de barras

  • En este ejercicio, calcularemos la media del índice HPI en un gráfico de barras utilizando un del código utilizado en el Ejercicio 33, añadiendo cálculo de la media en un gráfico de barras estático.

import altair as alt

bars = alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'mean(Happy Planet Index):Q',
).properties(width=400)

line = alt.Chart(hpi_df).mark_rule(color = 'firebrick').encode(
    y = 'mean(Happy Planet Index):Q',
    size = alt.SizeValue(3)
)

bars + line
  • Utilice el mecanismo de clic y arrastre utilizando el siguiente código en altair. Puede utilizar el mecanismo de clic y arrastre para seleccionar cualquier conjunto de barras y ver cómo la línea que indica la media del Happy Planet Index se desplaza en consecuencia.

import altair as alt

selected_bars = alt.selection(type = 'interval', encodings = ['x'])

bars = alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'mean(Happy Planet Index):Q',
    opacity = alt.condition(selected_bars, alt.OpacityValue(1), alt.OpacityValue(0.7)),
).properties(width=400).add_selection(
    selected_bars
)

line = alt.Chart(hpi_df).mark_rule(color = 'firebrick').encode(
    y = 'mean(Happy Planet Index):Q',
    size = alt.SizeValue(3)

).transform_filter(
    selected_bars
)

bars + line

Ejercicio 35: Añadir una función de zoom en un mapa de calor estático

  • En este ejercicio, utilizaremos altair para crear un mapa de calor que indique el número de países con el IPH y el Wellbeing en varios rangos. A continuación, añadiremos la función de zoom al mapa. También añadiremos círculos en el mapa de calor para mostrar diferentes países.

  • Importe los módulos de Python necesarios

import altair as alt
import pandas as pd
  • Lectura del conjunto de datos:

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Proporcione el DataFrame elegido (hpi_df en nuestro caso) a la función altair Chart. Utilice la función mark_rect() para indicar los puntos de datos en el gráfico de barras. Utilice la función encode para especificar las características en los ejes \(x\) e \(y\). Asigne a el parámetro bin en True para que ajuste automáticamente cada bin

alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Happy Planet Index:Q', bin=True),
    alt.Y('Wellbeing (0-10):Q', bin=True),
    alt.Color('count()', scale=alt.Scale(scheme='greenblue'), legend=alt.Legend(title='Total Countries'))
)
  • Utilice la función interactive y añada la capacidad de zoom. Utilice el siguiente código

alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Happy Planet Index:Q', bin = True),
    alt.Y('Wellbeing (0-10):Q', bin = True),
    alt.Color('count()', scale = alt.Scale(scheme='greenblue'), legend = alt.Legend(title='Total Countries'))
).interactive()
  • Al igual que podemos utilizar una paleta de colores para indicar el número de países en cada celda del mapa de calor, también podemos dibujar círculos de distintos tamaños en un mapa de calor para indicar el número de países. Dibuja círculos en el mapa térmico utilizando la función heatmap+circles. Los distintos tamaños de los círculos indican el número de países con un rango de Wellbeing variable.

heatmap = alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Happy Planet Index:Q', bin=True),
    alt.Y('Wellbeing (0-10):Q', bin=True)
)

circles = heatmap.mark_point().encode(
    alt.ColorValue('lightgray'),
    alt.Size('count()', legend=alt.Legend(title='Records in Selection'))
)
heatmap + circles

Ejercicio 36: Creación de un diagrama de barras y un mapa de calor contiguos

  • En este ejercicio, seguiremos trabajando con el conjunto de datos del IPH. El objetivo es dibujar un diagrama de barras que represente el número de países en cada región y un mapa de calor al lado, indicando el número de países en varios rangos de wellbeing y life-expectancy

  • Importe los módulos de Python necesarios

import altair as alt
import pandas as pd
  • Lectura del conjunto de datos:

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
  • Genere el gráfico de barras requerido utilizando la función mark_bar()

alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'count():Q'
).properties(width=350)
  • Genera el mapa de calor requerido utilizando la función mark_rect()

alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Wellbeing (0-10):Q', bin = True),
    alt.Y('Life Expectancy (years):Q', bin = True),
    alt.Color('count()', scale=alt.Scale(scheme='greenblue'), legend=alt.Legend(title='Total Countries'))
).properties(width=350)
  • Combine el código para colocar el gráfico de barras y el mapa de calor uno al lado del otro utilizando la función bars | heatmap

bars = alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'count():Q'
).properties(width=350)

heatmap = alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Wellbeing (0-10):Q', bin = True),
    alt.Y('Life Expectancy (years):Q', bin = True),
    alt.Color('count()', scale = alt.Scale(scheme = 'greenblue'), legend = alt.Legend(title = 'Total Countries'))
).properties(width=350)
bars | heatmap

Ejercicio 37: Vincular dinámicamente un gráfico de barras y un mapa de calor

  • En este ejercicio, enlazaremos un gráfico de barras y un mapa de calor de forma dinámica. Considere un escenario en el que desea poder hacer clic en cualquiera de las barras de un gráfico de barras y tener un mapa de calor correspondiente a la región representada por la barra. Así, por ejemplo, quiere actualizar el mapa térmico de la Life Expectancy frente al Well Being sólo para los países de una región determinada.

  • Importe los módulos de Python necesarios

import altair as alt
import pandas as pd
  • Lectura del conjunto de datos:

hpi_url = "https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/hpi_data_countries.tsv"
hpi_df = pd.read_csv(hpi_url, sep='\t')
hpi_df.head()
HPI Rank Country Region Life Expectancy (years) Wellbeing (0-10) Inequality of outcomes Ecological Footprint (gha/capita) Happy Planet Index
0 1 Costa Rica Americas 79.1 7.3 15% 2.8 44.7
1 2 Mexico Americas 76.4 7.3 19% 2.9 40.7
2 3 Colombia Americas 73.7 6.4 24% 1.9 40.7
3 4 Vanuatu Asia Pacific 71.3 6.5 22% 1.9 40.6
4 5 Vietnam Asia Pacific 75.5 5.5 19% 1.7 40.3
  • Seleccione la región mediante el método de selection

selected_region = alt.selection(type="single", encodings=['x'])

heatmap = alt.Chart(hpi_df).mark_rect().encode(
    alt.X('Wellbeing (0-10):Q', bin=True),
    alt.Y('Life Expectancy (years):Q', bin=True),
    alt.Color('count()', scale = alt.Scale(scheme = 'greenblue'), legend = alt.Legend(title = 'Total Countries'))
).properties(
    width=350
)
  • Colocar los círculos en un mapa de calor

circles = heatmap.mark_point().encode(
    alt.ColorValue('grey'),
    alt.Size('count()', legend = alt.Legend(title='Records in Selection'))
).transform_filter(
    selected_region
)
  • Utilice la función heatmap+circles | bars para vincular dinámicamente el gráfico de barras y el mapa de calor

bars = alt.Chart(hpi_df).mark_bar().encode(
    x = 'Region:N',
    y = 'count()',
    color = alt.condition(selected_region, alt.ColorValue("steelblue"), alt.ColorValue("grey"))
).properties(
    width=350
).add_selection(selected_region)

heatmap + circles | bars
  • Al hacer clic en cada gráfico de barras, verás que la paleta de colores que indica el total de países en de bienestar y esperanza de vida permanece constante, mientras que los círculos los círculos se actualizan para reflejar el número de países en el rango correspondiente para la región seleccionada.

  • La galería de ejemplos en https://altair-viz.github.io/gallery/index.html le proporcionará con una comprensión aún más profunda de las posibilidades de visualización en altair

  • En la sección anterior, presentamos una visión general de algunas formas importantes de añadir interactividad a los gráficos de barras y a los mapas de calor. En concreto, se ha aprendido

    • Cómo generar un gráfico de barras con la función altair mark_bar()

    • Cómo generar un mapa de calor utilizando la función altair mark_rect(), y cómo utilizar paletas de colores y círculos para representar visualmente los datos del mapa de calor

    • Cómo añadir capacidades de zoom a los gráficos de barras y a los mapas de calor utilizando la función función interactive()

    • Cómo utilizar la capacidad de estratificación en altair para presentar gráficos uno encima del otro utilizando la función layer() o el operador +

    • Cómo enlazar dinámicamente gráficos de barras y mapas de calor para crear una única y atractiva visualización

Tarea 1.4

  • Trabajaremos con el conjunto de datos de Google Play Store Apps alojado en googleplaystore.csv. Su tarea es crear una visualización con:

    • Un gráfico de barras de un número de aplicaciones estratificado por cada categoría Content Rating (calificado por Everyone/Teen).

    • Un mapa de calor que indica el número de aplicaciones estratificadas por app Category y rangos de rangos segmentados por Rating. El usuario debe poder interactuar con el gráfico seleccionando cualquiera de los tipos de Content Rating y el cambio correspondiente debería reflejarse en el mapa de calor para incluir sólo el número de aplicaciones en la categoría Content Rating.

  • Pasos principales

    • Descargue el conjunto de datos googleplaystore.csv y formatéelo como un pandas DataFrame

    • Elimina las entradas del DataFrame que tienen valores de característica de NA.

    • Cree el gráfico de barras necesario del número de aplicaciones en cada categoría Content Rating

    • Cree el mapa de calor necesario indicando el número de aplicaciones en la app en rangos Category y Rating

    • Combine el código del gráfico de barras y del mapa de calor y cree una visualización con ambos gráficos vinculados dinámicamente entre sí.

    • Interprete cada visualización

  • Algunas visualizaciones esperadas

df = pd.read_csv("https://raw.githubusercontent.com/lihkir/Uninorte/main/AppliedStatisticMS/DataVisualizationRPython/Lectures/Python/PythonDataSets/googleplaystore.csv")
df.head()
App Category Rating Reviews Size Installs Type Price Content Rating Genres Last Updated Current Ver Android Ver
0 Photo Editor & Candy Camera & Grid & ScrapBook ART_AND_DESIGN 4.1 159 19M 10,000+ Free 0 Everyone Art & Design January 7, 2018 1.0.0 4.0.3 and up
1 Coloring book moana ART_AND_DESIGN 3.9 967 14M 500,000+ Free 0 Everyone Art & Design;Pretend Play January 15, 2018 2.0.0 4.0.3 and up
2 U Launcher Lite – FREE Live Cool Themes, Hide ... ART_AND_DESIGN 4.7 87510 8.7M 5,000,000+ Free 0 Everyone Art & Design August 1, 2018 1.2.4 4.0.3 and up
3 Sketch - Draw & Paint ART_AND_DESIGN 4.5 215644 25M 50,000,000+ Free 0 Teen Art & Design June 8, 2018 Varies with device 4.2 and up
4 Pixel Draw - Number Art Coloring Book ART_AND_DESIGN 4.3 967 2.8M 100,000+ Free 0 Everyone Art & Design;Creativity June 20, 2018 1.1 4.4 and up